我写了一个类似这样的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

你知道问题出在哪里吗?


当前回答

在SQL Server 2017中,微软引入了一个带有分隔符的连接函数,仅针对您的情况:

SELECT CONCAT_WS(' ', first_name, last_name) FROM dbo.person

CONCAT_WS跳过NULL值,但不跳过空字符串。

有趣的是,MySQL早在十多年前就引入了CONCAT_WS。

其他回答

问题是null不被认为等于它自己,因此子句永远不匹配。

你需要显式检查null:

SELECT CASE WHEN last_name is NULL THEN first_name ELSE first_name + ' ' + last_name

给定你的查询,你也可以这样做:

SELECT first_name + ' ' + ISNULL(last_name, '') AS Name FROM dbo.person

有很多解决方案,但没有一个能解释为什么最初的陈述不起作用。

CASE last_name WHEN null THEN '' ELSE ' '+last_name

在when之后,有一个相等的检查,它应该是真或假。

如果比较的一个部分或两个部分都为null,则比较的结果将是UNKNOWN,在case结构中它被视为false。参见:https://www.xaprb.com/blog/2006/05/18/why-null-never-compares-false-to-anything-in-sql/

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

我试着转换到一个字符串,并测试一个零长度的字符串,它工作。

CASE 
   WHEN LEN(CAST(field_value AS VARCHAR(MAX))) = 0 THEN 
       DO THIS
END AS field 
CASE  
    WHEN last_name IS null THEN '' 
    ELSE ' ' + last_name 
END