Объединение строк в SQL Server с нулевым значением

Я создаю вычисляемый столбец для полей, некоторые из которых потенциально равны нулю.

Проблема в том, что если какое-либо из этих полей имеет значение NULL, весь вычисляемый столбец будет иметь значение NULL. Из документации Microsoft я понимаю, что это ожидается и может быть отключено с помощью параметра SET CONCAT_NULL_YIELDS_NULL. Однако я не хочу менять это поведение по умолчанию, потому что я не знаю, как это повлияет на другие части SQL Server.

Есть ли способ просто проверить, является ли столбец нулевым, и добавить его содержимое в формулу вычисляемого столбца только в том случае, если оно не равно нулю?


person Alex    schedule 26.05.2010    source источник
comment
Принятый ответ был правильным в то время, когда был задан вопрос, но для всех пользователей SQL Server 2012 и более поздних версий (и что этот этап должен быть у всех) ответ @ Martin-Smiths является лучшим, поскольку он автоматически обрабатывает значения NULL.   -  person Dowlers    schedule 15.08.2019


Ответы (9)


Вы можете использовать ISNULL(....)

SET @Concatenated = ISNULL(@Column1, '') + ISNULL(@Column2, '')

Если значение столбца / выражения действительно равно NULL, то вместо него будет использоваться второе указанное значение (здесь: пустая строка).

person marc_s    schedule 26.05.2010
comment
Coalesce - это стандартное имя функции ANSI, но ISNULL легче написать. - person Philip Kelley; 27.05.2010
comment
И ISNULL кажется немного быстрее и на SQL Server, поэтому, если вы хотите использовать его в функции, которая объединяет строки в вычисляемый столбец, вы можете отказаться от стандарта ANSI и выбрать скорость (см. Adam Machanic: sqlblog.com/blogs/adam_machanic/archive/2006 / 07/12 /) - person marc_s; 27.05.2010
comment
Просто использовал этот запрос Isnull (,), это очень помогло, поскольку я объединял значения вместе, и если одно из них было нулевым, все тоже становилось нулевым. - person Sizons; 03.02.2016
comment
Использование ISNULL() - хорошее решение, но начиная с SQL Server 2012 вы также можете использовать функцию CONCAT для получения того же результата: CONCAT(@Column1, @Column2) - person Muhammad Musavi; 24.06.2019
comment
@ Mohammadlm71: правильно, но это ответ был из 2010 года, когда SQL Server 2012 еще не появился; если вы все еще используете 2005, 2008 или 2008 R2, то это правильный путь. - person marc_s; 24.06.2019
comment
Здесь стоит отметить, что если вы хотите заменить null на что-то другое, кроме пустой строки, то есть IsNull(@Column1, 'NULLVALUE'), с IsNull длина заменяемой строки ограничена длиной заменяемого столбца, а с Coalesce это не так. - person Jamie; 29.10.2019

Начиная с SQL Server 2012 это все намного проще с функцией CONCAT.

Он рассматривает NULL как пустую строку

DECLARE @Column1 VARCHAR(50) = 'Foo',
        @Column2 VARCHAR(50) = NULL,
        @Column3 VARCHAR(50) = 'Bar';


SELECT CONCAT(@Column1,@Column2,@Column3); /*Returns FooBar*/
person Martin Smith    schedule 08.11.2013
comment
Для более старых версий вы получаете 'CONCAT' не распознанное имя встроенной функции, поэтому используйте COALESCE. - person Savage; 26.07.2016
comment
@Savage - COALESCE не будет работать, потому что он не объединяется, он просто возвращает первый ненулевой аргумент - person codeulike; 21.11.2018

Используйте COALESCE. Вместо your_column используйте COALESCE(your_column, ''). Это вернет пустую строку вместо NULL.

person Mark Byers    schedule 26.05.2010
comment
OP хочет объединить строки вместе, COALESCE этого не сделает - person codeulike; 21.11.2018

Вы также можете использовать CASE - мой код ниже проверяет как нулевые значения, так и пустые строки и добавляет разделитель, только если есть значение, которому нужно следовать:

SELECT OrganisationName, 
'Address' = 
CASE WHEN Addr1 IS NULL OR Addr1 = '' THEN '' ELSE Addr1 END + 
CASE WHEN Addr2 IS NULL OR Addr2 = '' THEN '' ELSE ', ' + Addr2 END + 
CASE WHEN Addr3 IS NULL OR Addr3 = '' THEN '' ELSE ', ' + Addr3 END + 
CASE WHEN County IS NULL OR County = '' THEN '' ELSE ', ' + County END 
FROM Organisations 
person Eddie    schedule 17.11.2013

Использовать

SET CONCAT_NULL_YIELDS_NULL  OFF 

и конкатенация нулевых значений в строку не приведет к нулевому значению.

Обратите внимание, что это устаревший вариант, избегайте использования. См. документацию для получения более подробной информации.

person Simran    schedule 07.02.2015

Я просто хотел внести свой вклад, если кому-то понадобится помощь с добавлением разделителей между строками, в зависимости от того, имеет ли поле значение NULL или нет.

Итак, в примере создания однострочного адреса из отдельных полей

Адрес1, Адрес2, Адрес3, Город, Почтовый индекс

в моем случае у меня есть следующий вычисляемый столбец, который, кажется, работает так, как я хочу:

case 
    when [Address1] IS NOT NULL 
    then (((          [Address1]      + 
          isnull(', '+[Address2],'')) +
          isnull(', '+[Address3],'')) +
          isnull(', '+[City]    ,'')) +
          isnull(', '+[PostCode],'')  
end

Надеюсь, это кому-то поможет!

person ebooyens    schedule 08.11.2013
comment
Там довольно много избыточных вложенных скобок, которые можно было бы удалить. Другой совет заключается в том, что вы также можете удалить оператор case, как если бы address1 был равен нулю, все выражение будет оцениваться как null (хотя наличие оператора case действительно привлекает внимание, что это может произойти) - person Alternator; 25.02.2014

У меня тоже было много проблем с этим. Не удалось заставить его работать, используя приведенные выше примеры случаев, но это делает мою работу за меня:

Replace(rtrim(ltrim(ISNULL(Flat_no, '') + 
' ' + ISNULL(House_no, '') + 
' ' + ISNULL(Street, '') + 
' ' + ISNULL(Town, '') + 
' ' + ISNULL(City, ''))),'  ',' ')

Заменить исправляет двойные пробелы, вызванные объединением одинарных пробелов, между которыми ничего нет. r / ltrim удаляет все пробелы на концах.

person BryDav    schedule 27.05.2016

На сервере Sql:

insert into Table_Name(PersonName,PersonEmail) values(NULL,'[email protected]')

PersonName is varchar(50), NULL is not a string, because we are not passing with in single codes, so it treat as NULL.

Отложенный код:

string name = (txtName.Text=="")? NULL : "'"+ txtName.Text +"'";
string email = txtEmail.Text;

insert into Table_Name(PersonName,PersonEmail) values(name,'"+email+"')
person Srinivasula Reddy    schedule 26.12.2012

Этот пример поможет вам обрабатывать различные типы при создании операторов вставки.

select 
'insert into doc(Id, CDate, Str, Code, Price, Tag )' + 
'values(' +
      '''' + convert(nvarchar(50), Id) + ''',' -- uniqueidentifier
    + '''' + LEFT(CONVERT(VARCHAR, CDate, 120), 10) + ''',' -- date
    + '''' + Str+ ''',' -- string
    + '''' + convert(nvarchar(50), Code)  + ''',' -- int
    + convert(nvarchar(50), Price) + ',' -- decimal
    + '''' + ISNULL(Tag, '''''') + '''' + ')'  -- nullable string

 from doc
 where CDate> '2019-01-01 00:00:00.000'
person Akmal Salikhov    schedule 18.02.2019