我写了一个类似这样的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为空也是如此。但是为什么呢?
我想做的是联合first_name和last_name,但如果last_name为空,整个名称变成空:
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
试试这个吧:
CASE LEN(ISNULL(last_Name,''))
WHEN 0 THEN ''
ELSE ' ' + last_name
END AS newlastName
LEN(ISNULL(last_Name, "))测量该列中的字符数,无论该列是空的还是空的,都将为零,因此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
问题是NULL不等于任何东西,甚至不等于它自己,但奇怪的是它也不等于它自己。
考虑以下语句(顺便说一下,这在SQL Server T-SQL中是非法的,但在My-SQL中是有效的,然而这是ANSI定义为null的,甚至可以在SQL Server中通过使用case语句等进行验证)
SELECT NULL = NULL——结果为NULL
SELECT NULL <> NULL——结果为NULL
所以这个问题没有真/假的答案,相反答案也是空的。
这有很多含义,例如
CASE语句,其中任何空值将始终使用ELSE子句,除非显式使用WHEN IS null条件(而不是WHEN null条件)
字符串连接,例如
SELECT a + NULL——结果为NULL
在WHERE In或WHERE NOT In子句中,如果你想要正确的结果,请确保在相关的子查询中过滤掉任何空值。
可以在SQL Server中通过指定SET ANSI_NULLS OFF来覆盖此行为,但是不建议这样做,因为它会导致许多问题,仅仅是因为标准的偏差。
(作为旁注,在My-SQL中有一个选项,可以使用特殊的操作符<=>进行空比较。)
相比之下,在一般编程语言中,null被视为常规值,等于自身,然而,NAN值也不等于自身,但至少它在与自身比较时返回'false'(以及在检查not =时,不同的编程语言有不同的实现)。
但是请注意,在基本语言(即VB等)中没有'null'关键字,而是使用'Nothing'关键字,这不能用于直接比较,而是需要像SQL中那样使用' is ',然而它实际上等于它本身(当使用间接比较时)。
Jason发现了一个错误,所以这可以工作…
有人能确认其他平台的版本吗?
SQL服务器:
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