如果我有这样的表:
+------------+
| Id | Value |
+------------+
| 1 | 'A' |
|------------|
| 1 | 'B' |
|------------|
| 2 | 'C' |
+------------+
如何获得这样的结果集:
+------------+
| Id | Value |
+------------+
| 1 | 'AB' |
|------------|
| 2 | 'C' |
+------------+
我知道使用GROUP_CONCAT在MySQL中很容易做到,但我需要能够在MSSQL 2005中做到这一点
由于
(How to use GROUP BY to concatenate strings in SQL Server?的重复)
答案 0 :(得分:10)
为了获得干净,高效的解决方案,您可以创建an user defined aggregate function,甚至an example可以满足您的需求。
然后,您可以像使用任何其他聚合函数一样使用它(使用标准查询计划):
答案 1 :(得分: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
答案 2 :(得分:4)
答案 3 :(得分:3)
经常asked here。
最有效的方法是使用FOR XML PATH技巧。
答案 4 :(得分: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