显示不在GROUP BY子句中的值的分隔字符串

时间:2013-12-17 13:46:34

标签: sql sql-server-2008-r2

当我有一个带有GROUP BY子句的SQL查询时,查看一些未分组的值以便于调试通常非常有用。

我的问题是,如何选择一个由未分组值组成的字符串 例如,在以下代码中:

SELECT  t2.ID 
        --,t1.Id    -- < how can I display this as a comma seperated string   
FROM t1 
     INNER JOIN t2 on t1.t2ID = t2.ID
GROUP BY t2.ID

我希望能够为每个分组记录选择一个包含t1.Id的字符串(例如"42, 13, 18" ...)。
我怎样才能做到这一点?

1 个答案:

答案 0 :(得分:1)

假设这些是整数值,您可以使用裸XML PATH转换为您处理组连接(这甚至支持可预测且定义良好的顺序,与所有其他组连接方法不同 - 它们具有未定义的行为)

DECLARE @t2 TABLE(ID INT);
DECLARE @t1 TABLE(ID INT IDENTITY(1,1),t2ID INT);

INSERT @t2(ID) VALUES(1),(2),(3);
INSERT @t1(t2ID) VALUES(1),(1),(1),(2);

SELECT t2.ID, t2IDs = STUFF((
  SELECT ',' + CONVERT(VARCHAR(11), t1.ID)
  FROM @t1 AS t1 WHERE t1.t2ID = t2.ID
  ORDER BY t1.ID
  FOR XML PATH('')),1,1,'')
FROM @t2 AS t2;

结果:

ID    t2IDs
----  -----
1     1,2,3
2     4
3     NULL

请注意,ID子句中不需要GROUP BY,因为您不再需要根据JOIN过滤掉匹配的重复项。当然,这假设您的列被恰当地命名 - 如果该列具有完全没有涉及JOIN的重复项,那么它具有非常误导性的名称。名为ID的列应唯一标识一行(但更好的方法是将其称为行,并在整个模型中将其命名为相同,例如CustomerIDOrderID,{{ 1}}等。)

如果您正在处理字符串,则需要考虑字符串可能包含XML不安全字符的情况(例如PatientID)。在这些情况下,这是我一直使用的方法:

<