Ответ 1
CASE WHEN last_name IS NULL THEN '' ELSE ' '+last_name END
Я написал выражение T-SQL, подобное этому (оригинал выглядит по-другому, но я хочу привести здесь простой пример):
SELECT first_name +
CASE last_name WHEN null THEN 'Max' ELSE 'Peter' END AS Name
FROM dbo.person
В этом заявлении нет синтаксических ошибок, но case-clause всегда выбирает ELSE-часть - также, если last_name равно null. Но почему?
Что я хочу сделать, так это объединить имя_имя и last_name, но если last_name равно null, все имя становится null:
SELECT first_name +
CASE last_name WHEN null THEN '' ELSE ' ' + last_name END AS Name
FROM dbo.person
Вы знаете, где проблема?
CASE WHEN last_name IS NULL THEN '' ELSE ' '+last_name END
Часть WHEN сравнивается с ==, но вы не можете сравнить ее с NULL. Попробуйте
CASE WHEN last_name is NULL THEN ... ELSE .. END
или COALESCE:
COALESCE(' '+last_name,'')
('' + last_name NULL, когда last_name NULL, поэтому в этом случае он должен возвращать ''
С учетом вашего запроса вы также можете сделать это:
SELECT first_name + ' ' + ISNULL(last_name, '') AS Name FROM dbo.person
Проблема в том, что null не считается равным себе, поэтому предложение никогда не совпадает.
Вам нужно явно указать значение null:
SELECT CASE WHEN last_name is NULL THEN first_name ELSE first_name + ' ' + last_name
Существует множество решений, но никто не объясняет, почему исходный оператор не работает.
CASE last_name WHEN null THEN '' ELSE ' '+last_name
После того, как происходит проверка, выполняется равенство, которое должно быть истинным или ложным.
Если одна или обе части сравнения являются нулевыми, результат сравнения будет UNKNOWN, который обрабатывается как ложный в структуре случая. См.: https://www.xaprb.com/blog/2006/05/18/why-null-never-compares-false-to-anything-in-sql/
Чтобы избежать этого, Coalesce - лучший способ.
попробовать:
SELECT first_name + ISNULL(' '+last_name, '') AS Name FROM dbo.person
Это добавляет пробел к фамилии, если оно равно null, все пробел + фамилия переходит в NULL, и вы получаете только имя, иначе вы получите имя firts + space + last.
это будет работать до тех пор, пока задано значение по умолчанию для конкатенации с нулевыми строками:
SET CONCAT_NULL_YIELDS_NULL ON
это не должно вызывать беспокойства, так как режим OFF
уходит в будущих версиях SQl Server
Проблема в том, что NULL не считается равным ничему, даже не самому себе, но странная часть - это то же, что и не сама по себе.
Рассмотрим следующие утверждения (которые являются BTW незаконными в SQL Server T-SQL, но действительны в My-SQL, однако это то, что ANSI определяет для null, и может быть проверено даже в SQL Server с помощью операторов case и т.д.).
SELECT NULL = NULL -- Results in NULL
SELECT NULL <> NULL -- Results in NULL
Таким образом, нет истинного/ложного ответа на вопрос, вместо этого ответ также является нулевым.
Это имеет много последствий, например, в
WHEN NULL
)SELECT a + NULL -- Results in NULL
Можно переопределить это поведение в SQL Server, указав SET ANSI_NULLS OFF
, однако это НЕ рекомендуется и не должно выполняться, поскольку это может вызвать множество проблем, просто потому, что отклонение стандарта.
(В качестве побочного примечания в My-SQL существует опция использования специального оператора <=>
для нулевого сравнения.)
Для сравнения, в общем случае языки программирования null обрабатываются как регулярное значение и равно самому себе, однако значение NAN также не равно самому себе, но по крайней мере оно возвращает "false" при сравнении его с самим собой, (и при проверке не равны разные языки программирования имеют разные реализации).
Обратите внимание, что в базовых языках (т.е. VB и т.д.) ключевое слово "null" отсутствует, и вместо этого используется ключевое слово "Nothing", которое нельзя использовать в прямом сравнении, и вместо этого нужно использовать "IS" как в SQL, однако он фактически равен самому себе (при использовании косвенных сравнений).
CASE
WHEN last_name IS null THEN ''
ELSE ' ' + last_name
END
Когда вы расстраиваетесь, попробуйте это:
CASE WHEN last_name IS NULL THEN '' ELSE ' '+last_name END
Попробуйте вместо этого:
CASE LEN(ISNULL(last_Name,''))
WHEN 0 THEN ''
ELSE ' ' + last_name
END AS newlastName
LEN(ISNULL(last_Name,''))
измеряет количество символов в этом столбце, которое будет равно нулю, пустое или NULL, поэтому WHEN 0 THEN
будет оценивать значение true и возвращать '' как ожидалось.
Надеюсь, это полезная альтернатива.
Я включил этот тестовый пример для SQL Server 2008 и выше:
DECLARE @last_Name varchar(50) = NULL
SELECT
CASE LEN(ISNULL(@last_Name,''))
WHEN 0 THEN ''
ELSE 'A ' + @last_name
END AS newlastName
SET @last_Name = 'LastName'
SELECT
CASE LEN(ISNULL(@last_Name,''))
WHEN 0 THEN ''
ELSE 'A ' + @last_name
END AS newlastName
Джейсон ошибся, поэтому это работает...
Кто-нибудь может подтвердить другие версии платформы? SQL Server:
SELECT
CASE LEN(ISNULL(last_name,''))
WHEN 0 THEN ''
ELSE ' ' + last_name
END AS newlastName
MySQL:
SELECT
CASE LENGTH(IFNULL(last_name,''))
WHEN 0 THEN ''
ELSE ' ' + last_name
END AS newlastName
Oracle:
SELECT
CASE LENGTH(NVL(last_name,''))
WHEN 0 THEN ''
ELSE ' ' + last_name
END AS newlastName
Вы можете использовать функцию IsNull
select
isnull(rtrim(ltrim([FirstName]))+' ','') +
isnull(rtrim(ltrim([SecondName]))+' ','') +
isnull(rtrim(ltrim([Surname]))+' ','') +
isnull(rtrim(ltrim([SecondSurname])),'')
from TableDat
если один столбец равен null, вы получите пустой char
Совместимость с Microsoft SQL Server 2008 +
Я попробовал кастинг на строку и тестирование строки нулевой длины, и она сработала.
CASE
WHEN LEN(CAST(field_value AS VARCHAR(MAX))) = 0 THEN
DO THIS
END AS field
Используйте функцию CONCAT, доступную в SQL Server 2012.
SELECT CONCAT([FirstName], ' , ' , [LastName]) FROM YOURTABLE