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

所以这个问题没有真正的答案,而是答案也是空的。

这有很多含义,例如

  1. CASE语句,其中任何空值将始终使用ELSE子句,除非明确使用WHEN IS NULL条件( NOT WHEN NULL条件)
  2. string连接,如
    SELECT a + NULL -- Results in NULL
  3. 在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字段