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


85

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

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

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


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

Ответы:


142

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

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

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


22
«Coalesce» - это стандартное имя функции ANSI, но ISNULL легче написать.
Филип Келли

1
И ISNULL кажется немного быстрее и на SQL Server, поэтому, если вы хотите использовать его в функции, которая объединяет строки в вычисляемый столбец, вы можете отказаться от стандарта ANSI и выбрать скорость (см. Адам Мачаник: sqlblog.com / blogs / adam_machanic / archive / 2006/07/12 /… )
marc_s

Просто использовал этот запрос Isnull (,), он очень помог, поскольку я объединял значения вместе, и если одно из них было нулевым, все тоже становилось нулевым.
Sizons

Использование ISNULL()- хорошее решение, но начиная с SQL Server 2012, вы также можете использовать CONCATфункцию для получения того же результата:CONCAT(@Column1, @Column2)
Мухаммад Мусави,

2
Здесь стоит отметить, что если вы хотите поменять местами null что-то другое, кроме пустой строки, то есть IsNull(@Column1, 'NULLVALUE')при IsNullзамене длина строки ограничена длиной заменяемого столбца, в то время как это не такCoalesce
Джейми

58

Начиная с 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*/

Благодарность! Это было то, что мне было нужно !!
Шива

Для более старых версий вы получите «'CONCAT' не является распознанным именем встроенной функции», поэтому используйте COALESCE
Savage,

3
@Savage - COALESCE не будет работать, потому что он не объединяется, он просто возвращает первый ненулевой аргумент
codeulike

30

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


OP хочет объединить строки вместе, COALESCE этого не сделает
codeulike

12

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

SET CONCAT_NULL_YIELDS_NULL  OFF 

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

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


11

Вы также можете использовать 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 

8

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

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

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

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

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

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


Там довольно много избыточных вложенных скобок, которые можно было бы удалить. Еще один совет: вы также можете удалить оператор case, как если бы address1 был равен нулю, все выражение будет оцениваться как null (хотя наличие оператора case действительно привлекает внимание, что это может произойти)
Альтернатор


1

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

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

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


0

На сервере Sql:

insert into Table_Name(PersonName,PersonEmail) values(NULL,'xyz@xyz.com')

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+"')

0

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

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'
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.