10

如果我有这样的表:

+------------+
| Id | Value |
+------------+
| 1  | 'A'   |
|------------|
| 1  | 'B'   |
|------------|
| 2  | 'C'   |
+------------+

我怎样才能得到这样的结果集:

+------------+
| Id | Value |
+------------+
| 1  | 'AB'  |
|------------|
| 2  | 'C'   |
+------------+

我知道在 MySQL 中使用 GROUP_CONCAT 很容易做到这一点,但我需要能够在 MSSQL 2005 中做到这一点

谢谢

(复制SQL Server 中如何使用 GROUP BY 连接字符串?

4

5 回答 5

11

对于一个干净高效的解决方案,您可以创建一个用户定义的聚合函数,甚至还有一个示例可以满足您的需要。
然后,您可以像使用任何其他聚合函数一样使用它(使用标准查询计划):

查询计划

于 2009-12-17T15:31:39.490 回答
5

这将做:

SELECT mt.ID,
       SUBSTRING((SELECT mt2.Value
                  FROM   MyTable AS mt2
                  WHERE  mt2.ID = mt.ID
                  ORDER BY mt2.VALUE
                  FOR XML PATH('')), 3, 2000) AS JoinedValue
FROM   MyTable AS mt
于 2009-06-02T18:29:10.233 回答
4

看:

http://blog.shlomoid.com/2008/11/emulating-mysqls-groupconcat-function.html

于 2009-06-02T18:27:07.990 回答
3

经常在这里问

最有效的方法是使用 FOR XML PATH 技巧。

于 2009-06-02T18:28:32.513 回答
1

这只是作为一种可能的解决方案来找我。我对性能一无所知,但我认为这将是解决问题的一种有趣方式。我测试了它在一个简单的情况下工作(我没有编码来解释 NULL)。随意给它一个测试,看看它是否适合你。

我使用的表包含一个 id (my_id)。这实际上可以是组中唯一的任何列 (grp_id),因此它可以是日期列或其他任何内容。

;WITH CTE AS (
    SELECT
        T1.my_id,
        T1.grp_id,
        CAST(T1.my_str AS VARCHAR) AS my_str
    FROM
        dbo.Test_Group_Concat T1
    WHERE NOT EXISTS (SELECT * FROM dbo.Test_Group_Concat T2 WHERE T2.grp_id = T1.grp_id AND T2.my_id < T1.my_id)
    UNION ALL
    SELECT
        T3.my_id,
        T3.grp_id,
        CAST(CTE.my_str + T3.my_str AS VARCHAR)
    FROM
        CTE
    INNER JOIN dbo.Test_Group_Concat T3 ON
        T3.grp_id = CTE.grp_id AND
        T3.my_id > CTE.my_id
    WHERE
        NOT EXISTS (SELECT * FROM dbo.Test_Group_Concat T4 WHERE
        T4.grp_id = CTE.grp_id AND
        T4.my_id > CTE.my_id AND
        T4.my_id < T3.my_id)
)
SELECT
    CTE.grp_id,
    CTE.my_str
FROM
    CTE
INNER JOIN (SELECT grp_id, MAX(my_id) AS my_id FROM CTE GROUP BY grp_id) SQ ON
    SQ.grp_id = CTE.grp_id AND
    SQ.my_id = CTE.my_id
ORDER BY
    CTE.grp_id
于 2009-06-02T18:49:56.543 回答