T-SQL CASE子句:如何指定WHEN NULL

men*_*eni 208 t-sql

我写了一个类似这样的T-SQL语句(原始的一个看起来不同但我想在这里给出一个简单的例子):

SELECT first_name + 
    CASE last_name WHEN null THEN 'Max' ELSE 'Peter' END AS Name
FROM dbo.person
Run Code Online (Sandbox Code Playgroud)

此语句没有任何语法错误,但case子句始终选择ELSE部分 - 如果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
Run Code Online (Sandbox Code Playgroud)

你知道问题出在哪里吗?

Mar*_*tos 352

CASE WHEN last_name IS NULL THEN '' ELSE ' '+last_name END
Run Code Online (Sandbox Code Playgroud)

  • @ Luther的COALESCE建议比我的回答更好.效率略低,但更优雅. (2认同)

Nor*_*ame 37

WHEN部分与==进行比较,但您无法与NULL进行比较.尝试

CASE WHEN last_name is NULL  THEN ... ELSE .. END
Run Code Online (Sandbox Code Playgroud)

相反或COALESCE:

COALESCE(' '+last_name,'')
Run Code Online (Sandbox Code Playgroud)

(当last_name为NULL时,''+ last_name为NULL,因此在这种情况下应返回'')


Ian*_*obs 11

根据您的查询,您也可以这样做:

SELECT first_name + ' ' + ISNULL(last_name, '') AS Name FROM dbo.person
Run Code Online (Sandbox Code Playgroud)

  • 最好使用`ISNULL(''+ last_name,'')`来防止冗余空间. (6认同)
  • 当last_name为null时,这会增加一个冗余空间,这是OP试图避免的. (2认同)

kam*_*ahl 11

有很多解决方案,但没有解决为什么原始声明不起作用.

CASE last_name WHEN null THEN '' ELSE ' '+last_name
Run Code Online (Sandbox Code Playgroud)

在什么时候之后,检查是否相等,这应该是真或假.

如果比较的一个或两个部分为空,则比较结果将为UNKNOWN,在案例结构中将其视为false.请参阅:https://www.xaprb.com/blog/2006/05/18/why-null-never-compares-false-to-anything-in-sql/

为了避免这种情况,Coalesce是最好的方法.


b0f*_*0fh 7

问题是null不被认为与自身相等,因此该子句永远不会匹配.

您需要明确检查null:

SELECT CASE WHEN last_name is NULL THEN first_name ELSE first_name + ' ' + last_name
Run Code Online (Sandbox Code Playgroud)


KM.*_*KM. 5

尝试:

SELECT first_name + ISNULL(' '+last_name, '') AS Name FROM dbo.person
Run Code Online (Sandbox Code Playgroud)

这增加了空间的姓氏,如果是空,整个空间+姓去为NULL,你只能得到一个名字,否则,你得到一个firts +空格+姓氏.

只要设置了与空字符串串联的默认设置,这将起作用:

SET CONCAT_NULL_YIELDS_NULL ON 
Run Code Online (Sandbox Code Playgroud)

这不应该是一个问题,因为该OFF模式将在未来版本的SQl Server中消失


yoe*_*alb 5

问题是 NULL 不被认为等于任何东西,甚至不等于它自己,但奇怪的是它也不等于它自己。

考虑以下语句(顺便说一句,这在 SQL Server T-SQL 中是非法的,但在 My-SQL 中有效,但是这是 ANSI 为 null 定义的,即使在 SQL Server 中也可以通过使用 case 语句等进行验证)

SELECT NULL = NULL -- Results in NULL

SELECT NULL <> NULL -- Results in NULL

所以这个问题没有真/假答案,相反,答案也是空的。

这有很多含义,例如在

  1. CASE语句,其中除非您使用显式的任何空值将始终使用ELSE子句当NULL条件(NOTWHEN NULL条件
  2. 字符串连接,如
    SELECT a + NULL -- Results in NULL
  3. 在 WHERE IN 或 WHERE NOT IN 子句中,如果您想要正确的结果,请确保在相关子查询中过滤掉任何空值。

可以通过指定在 SQL Server 中覆盖此行为SET ANSI_NULLS OFF,但是建议这样做,也不应该这样做,因为它会导致许多问题,仅仅是因为偏离标准。

(作为旁注,在 MySQL 中有一个选项可以使用特殊运算符<=>进行空比较。)

相比之下,在一般的编程语言中,null 被视为一个常规值并等于自身,但是 NAN 值也不等于自身,但至少在与自身比较时返回“假”,(和当检查不等于时,不同的编程语言有不同的实现)。

但是请注意,在基本语言(即 VB 等)中,没有“null”关键字,而是使用“Nothing”关键字,该关键字不能用于直接比较,而需要像在 SQL 中一样使用“IS”,然而它实际上等于它自己(当使用间接比较时)。