T-SQL CASE子句:如何指定WHEN NULL
我写了一个像这样的T-SQL语句(原来的看起来不一样,但我想在这里给一个简单的例子):
SELECT first_name + CASE last_name WHEN null THEN 'Max' ELSE 'Peter' END AS Name FROM dbo.person
此语句没有任何语法错误,但case-clause总是selectELSE-part – 如果last_name为null。 但为什么?
我想要做的是统一first_name和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
有很多的解决scheme,但没有涵盖为什么原来的声明不起作用。
CASE last_name WHEN null THEN '' ELSE ' '+last_name
之后,有一个平等的检查,这应该是真的或假的。
如果比较的一个或两个部分为空,则比较的结果将是UNKNOWN,在case结构中被视为false。 请参阅: 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,你只有一个名字,否则你会得到一个firts +空格+姓氏。
只要设置了与空string连接的默认设置,就会工作:
SET CONCAT_NULL_YIELDS_NULL ON
这不应该成为一个问题,因为OFF
模式在SQl服务器的未来版本中将会消失
问题在于,NULL不被认为与任何东西都是相等的,但是奇怪的是它也不等于它本身。
考虑下面的语句(在SQL Server T-SQL中是BTW非法,但在My-SQL中是有效的,但这是ANSI为null定义的内容,甚至可以在SQL Server中通过使用case语句来validation)
SELECT NULL = NULL -- Results in NULL
SELECT NULL <> NULL -- Results in NULL
所以这个问题没有真正的答案,而是答案也是空的。
这有很多含义,例如
- CASE语句,其中任何空值将始终使用ELSE子句,除非明确使用WHEN IS NULL条件( NOT
WHEN NULL
条件) - string连接,如
SELECT a + NULL -- Results in NULL
- 在WHERE IN或WHERE NOT IN子句中,就好像你想要正确的结果一样,确保在相关的子查询中过滤掉任何空值。
可以通过指定SET ANSI_NULLS OFF
来覆盖SQL Server中的这种行为,但是这不是build议的,不应该这样做,因为它可能会导致很多问题,只是因为标准的偏差。
(作为一个方面说明,在My-SQL中,可以使用特殊的运算符<=>
进行空比较。
相比之下,在一般的编程语言中,null被处理是一个正常值,并且等于它本身,但是NAN值也不等于它本身,但是至less当它与自身比较时它返回“假”(和当检查不等于不同的编程语言有不同的实现)。
但是请注意,在基本语言(即VB等)中没有“null”关键字,而是使用“Nothing”关键字,不能用于直接比较,而是需要使用SQL中的“IS”然而它实际上等于它自己(当使用间接比较的时候)。
CASE WHEN last_name IS null THEN '' ELSE ' ' + last_name END
杰森发现了一个错误,所以这个工程…
任何人都可以确认其他平台版本?
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
甲骨文:
SELECT CASE LENGTH(NVL(last_name,'')) WHEN 0 THEN '' ELSE ' ' + last_name END AS newlastName
当你感到沮丧尝试这个:
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,并按预期返回“”。
我希望这是一个有益的select。
我已经包含了SQL Server 2008及以上的testing用例:
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
您可以使用IsNull函数
select isnull(rtrim(ltrim([FirstName]))+' ','') + isnull(rtrim(ltrim([SecondName]))+' ','') + isnull(rtrim(ltrim([Surname]))+' ','') + isnull(rtrim(ltrim([SecondSurname])),'') from TableDat
如果一列是空的,你会得到一个空字符
与Microsoft SQL Server 2008+兼容
我试图铸造一个string,并testing一个零长度的string,它的工作。
CASE WHEN LEN(CAST(field_value AS VARCHAR(MAX)))= 0那么做这个END AS字段