SQL Server 2012 无法正常工作的多个项目的逗号分隔

Comma separated for multiple items not working properly for SQL Sever 2012

我正在使用 SQL Server 2012 (v11.0.5058.0 - X64)。我想为多列执行逗号分隔。由于我的 SQL 服务器版本是 2012 我不能使用 string_aggListAgg 所以我正在尝试使用 CTE 和 FOR XML PATH 这对我来说是新的。

输出解释:

假设如果一个staff ID包含多个Cost_Center那么它应该为各自的Staff_ID

逗号分隔

当前 table:

Staff_No |  Name  | CostCenter     |  status  |
---------+--------+----------------+----------+
1270     | WASI   | 850110 - CPP   |   Active |
1345     | FAK    | 124600 - CPP   |   Active |
1270     | WASI   | 850870 - BKR   |   Active |

期望的输出:

Staff_No |  Name  | CostCenter                   |  status  |
---------+--------+------------------------------+----------+
1270     | WASI   | 850110 - CPP , 850870 - BKR  |   Active |
1345     | FAK    | 124600 - CPP                 |   Active |

我试过这段代码:

WITH CTE_TableName AS 
(
    SELECT   
        a.Staff_No, a.Name,  
        CONVERT(varchar(19), a.COST_CENTER_CODE) + ' - ' + b.COST_CENTER_DESC  as CostCenter,   
        CASE a.Active 
           WHEN 1 THEN 'Active' 
           WHEN 2 THEN 'Inactive' 
        END AS status   
   FROM
       [FAV_VS_STAFF_M] a, [FAV_VS_COST_CENTER_M] b 
)
SELECT 
    t0.Staff_No, t0.Name, t0.status,
    STUFF((SELECT ',' + t2.CostCenter
           FROM CTE_TableName t2
           WHERE t2.Staff_No = t0.Staff_No
           ORDER BY t2.CostCenter
           FOR XML PATH('')), 1, LEN(','), '') AS FieldBs
FROM 
    CTE_TableName t0
GROUP BY 
    t0.Staff_No , t0.Name, t0.status
ORDER BY 
    Staff_No;

我没有得到想要的输出。我哪里出错了?请帮助我

通常,SELECT .. FOR XML ..WHERE 子句应该使子查询依赖于在外部查询的 GROUP BY 子句中列出的完全相同的列。尝试

WITH CTE_TableName AS (
        SELECT   a.Staff_No , a.Name , 
        CONVERT(varchar(19), a.COST_CENTER_CODE) + ' - ' + b.COST_CENTER_DESC  as CostCenter,   
CASE a.Active WHEN 1 THEN 'Active' WHEN 2 THEN 'Inactive' END AS status   
from [FAV_VS_STAFF_M] a, [FAV_VS_COST_CENTER_M] b )
SELECT t0.Staff_No, t0.Name , t0.status
     , STUFF((
       SELECT ',' + t2.CostCenter
         FROM CTE_TableName t2
        WHERE t2.Staff_No = t0.Staff_No
            AND t2.Name = t0.Name AND t2.status = t0.status
        ORDER BY t2.CostCenter
          FOR XML PATH('')), 1, LEN(','), '') AS FieldBs
  FROM CTE_TableName t0
  GROUP BY t0.Staff_No , t0.Name, t0.status
  ORDER BY Staff_No;

db<>fiddle

如果您只想要不同的值,您需要在内部 SELECT 中使用 DISTINCTGROUP BY 子句。 有许多方法,最简单的是:

    STUFF((SELECT DISTINCT ',' + t2.CostCenter
           FROM CTE_TableName t2
           WHERE t2.Staff_No = t0.Staff_No
             AND t2.Name = t0.Name AND t2.status = t0.status
           ORDER BY 1
           FOR XML PATH(''), TYPE).value('text()[1]','nvarchar(max)')
    , 1, LEN(','), '') AS FieldBs

注意添加 TYPEvalue('text()[1]','nvarchar(max)') 以确保 XML 正确转义。

如@Serg 所述,您还需要正确关联连接 AND t2.Name = t0.Name AND t2.status = t0.status

给这只猫剥皮的另一种方法:

    STUFF((SELECT DISTINCT ',' + t2.CostCenter
           FROM CTE_TableName t2
           WHERE t2.Staff_No = t0.Staff_No
             AND t2.Name = t0.Name AND t2.status = t0.status
           ORDER BY ',' + t2.CostCenter
           FOR XML PATH(''), TYPE).value('text()[1]','nvarchar(max)')
    , 1, LEN(','), '') AS FieldBs

或者:

    STUFF((SELECT ',' + t2.CostCenter
           FROM CTE_TableName t2
           WHERE t2.Staff_No = t0.Staff_No
             AND t2.Name = t0.Name AND t2.status = t0.status
           GROUP BY ',' + t2.CostCenter
           ORDER BY ',' + t2.CostCenter
           FOR XML PATH(''), TYPE).value('text()[1]','nvarchar(max)')
    , 1, LEN(','), '') AS FieldBs

请参阅 this question 了解为什么需要这样指定 ORDER BY