【问题标题】:SQL Server : Case with function callsSQL Server:函数调用案例
【发布时间】:2018-07-19 17:49:50
【问题描述】:

表格是:

+----+------+
| Id | Name |
+----+------+    
| 1  | aaa  |
| 1  | bbb  |
| 1  | ccc  |
| 1  | ddd  |
| 1  | eee  |
+----+------+

需要的输出:

+----+---------------------+
| Id |        abc          |
+----+---------------------+ 
|  1 | aaa,bbb,ccc,ddd,eee |
+----+---------------------+

查询:

SELECT 
    ID, 
    abc = STUFF((SELECT ',' + name 
                 FROM temp1 
                 FOR XML PATH ('')), 1, 1, '') 
FROM 
    temp1 
GROUP BY 
    id

此查询工作正常。我现在想做的是在选择中添加case 语句。如果 XML 为 NULL,则显示“未找到名称”,但当我尝试执行此操作时 SQL Server 会抛出错误。

这样使用时会抛出此错误(见下文)

SELECT
    ID, 
    abc = CASE 
             STUFF((SELECT ',' + name 
                    FROM temp1 
                    FOR XML PATH ('')), 1, 1, '') IS NOT NULL 
             THEN abc
             ELSE 'No names found'
FROM 
    temp1 
GROUP BY 
    id

错误:

在预期条件的上下文中指定的非布尔类型的表达式

或者这样使用时

SELECT 
    ID, 
    CASE abc = STUFF((SELECT ',' + name 
                      FROM temp1 
                      FOR XML PATH ('')), 1, 1, '') IS NOT NULL 
       THEN abc 
       ELSE 'No names found'
FROM 
    temp1 
GROUP BY 
    id

错误:

列名 abc 无效

如何向case 语句添加函数调用?

【问题讨论】:

  • 您在 CASE 语句中的语法不正确。 CASE 结构为CASE <Test> <Action>CASE <Value> <IsValue?> <Action>。你的语法是CASE <Action> <Test> <Action>

标签: sql sql-server case


【解决方案1】:

模板:

CASE WHEN test expression THEN resultant ELSE default value END

第一关

SELECT ID, 
    abc = CASE WHEN STUFF((SELECT ',' + name FROM temp1 FOR XML PATH ('')), 1, 1, '') IS NOT NULL
        THEN CASE WHEN STUFF((SELECT ',' + name FROM temp1 FOR XML PATH ('')), 1, 1, '')
    ELSE 'No names found' END
FROM temp1 
GROUP BY id;

使用CTE不必放两次大表情

WITH cte as (SELECT ID, 
        abc = ((SELECT ',' + name FROM temp1 FOR XML PATH ('')), 1, 1, '')
    FROM temp1
    GROUP BY id)
SELECT ID,
    CASE WHEN abc IS NOT NULL THEN abc ELSE 'No names found' AS abc2
FROM cte;

在这种特定情况下使用COALESCE

SELECT ID, 
    abc = COALESCE(STUFF((SELECT ',' + name FROM temp1 FOR XML PATH ('')), 1, 1, '')
         , 'No names found')
FROM temp1 
GROUP BY id;

【讨论】:

  • 感谢 CTE,从没想过要走那条路。当Coalesce 不是一个可行的选择时,这似乎是一个很好的解决方案。
【解决方案2】:

你可以这样做:

SELECT ID, COALESCE(STUFF( (SELECT ',' + t1.name 
                            FROM temp1 t1
                            WHERE t1.id = t.id -- perhaps you need this
                            FOR XML PATH ('')
                           ), 1, 1, ''
                          ), 'No names found'
                   ) AS abc
FROM temp1 t
GROUP BY id;

但是,我不知道您如何通过前面的查询与同一张表获得@9​​87654322@?

【讨论】:

    【解决方案3】:

    你可以像这样使用 COALESCE 函数

     SELECT ID, 
       abc =  COALESCE( STUFF( (
                 (SELECT ',' + name FROM temp1 FOR XML PATH ('')), 1, 1, ''
               ) , 'No names found')
    FROM temp1 GROUP BY id
    

    【讨论】:

      【解决方案4】:

      当您的查询中缺少关键字时。

      CASE WHEN 表达式 THEN ... ELSE ... END

      【讨论】:

      • 正确...但是这里还有更多内容,您不能像在then 子句之后那样简单地引用abc...
      【解决方案5】:

      选择 ID, abc = 案例 东西((选择','+名称 从温度 1 FOR XML PATH ('')), 1, 1, '') 不为空 然后东西((选择','+名称 从温度 1 FOR XML PATH ('')), 1, 1, '') ELSE '未找到名称' 从 温度1 通过...分组 身份证

      【讨论】:

        【解决方案6】:

        你可以说

        SELECT 
            ID, 
            ISNULL(STUFF((SELECT ',' + name 
                              FROM temp1 
                              FOR XML PATH ('')), 1, 1, ''),'No names found') AS 'abc'
        FROM 
            temp1 
        GROUP BY 
            id
        

        你不需要案例陈述

        【讨论】:

          猜你喜欢
          • 2014-10-17
          • 1970-01-01
          • 1970-01-01
          • 2012-04-28
          • 2013-10-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多