sql returns 连接声明的列并定义它时如何显示所有行?

How does sql returns all rows when concating declared column and defining it?

这在 SQL 中怎么可能?

DECLARE @liststr VARCHAR(MAX)
;WITH COMMA (name)
AS
(
    SELECT 'a' 
    UNION
    SELECT 'b'
    UNION
    SELECT 'c'
    UNION
    SELECT 'd'
)
SELECT @liststr = CASE WHEN  @liststr+',' IS NULL THEN '' ELSE @liststr+',' END + name 
FROM comma

SELECT @liststr as Result

以上查询返回以下结果

+---------+
| Result  |
+---------+
| a,b,c,d |
+---------+

如果我们删除 case 语句。

DECLARE @liststr VARCHAR(MAX)
;WITH COMMA (name)
AS
(
    SELECT 'a' 
    UNION
    SELECT 'b'
    UNION
    SELECT 'c'
    UNION
    SELECT 'd'
)
SELECT @liststr = @liststr+',' + name FROM comma
SELECT @liststr as Result

结果是

+--------+
| Result |
+--------+
| NULL   |
+--------+

完全没有。当 SQL 服务器将字符串连接到 NULL 值时,该值是 NULL.

如果您首先将值设置为空字符串,那么两者将 return 相同的值:

DECLARE @liststr VARCHAR(MAX);
SET @liststr = '';

两个注意事项:

  • 使用 union all 而不是 union,除非您明确希望承担删除重复项的开销。
  • 当运行查询时,结果是任意顺序的。如果您想要特定的顺序,请使用 order by.

注意Erland Sommarskog表示不支持这种组合字符串的方法。虽然他建议在这个特定答案中使用光标,但我会使用 XML.

您可以使用SQL服务器的CONCAT功能:

SELECT @liststr = CONCAT(@liststr, ',', name) FROM comma
SELECT @liststr AS myString 

因此,如果 CONCAT 中的一个参数为 NULL,它将被替换为一个空字符串。