Concat Gruppen in SQL Server [Duplikat]
-
06-09-2019 - |
Frage
Diese Frage bereits eine Antwort hier:
Wenn ich eine Tabelle wie folgt aus:
+------------+
| Id | Value |
+------------+
| 1 | 'A' |
|------------|
| 1 | 'B' |
|------------|
| 2 | 'C' |
+------------+
Wie kann ich eine resultset wie diese:
+------------+
| Id | Value |
+------------+
| 1 | 'AB' |
|------------|
| 2 | 'C' |
+------------+
Ich weiß, das ist wirklich einfach in MySQL zu tun GROUP_CONCAT, aber ich muss in der Lage, es in MSSQL 2005 zu tun
Danke
(Duplizieren von Wie GROUP BY verwenden, um verketten Zeichenfolgen in SQL Server? )
Lösung
Für eine saubere und effiziente Lösung, können Sie erstellen eine benutzerdefinierte Aggregatfunktion , gibt es sogar ein Beispiel das tut genau das, was Sie müssen.
Sie können dann verwenden, wie jede andere Aggregatfunktion (mit einem Standard-Abfrage-Plan):
Andere Tipps
Dies wird tun:
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
Oft fragte hier .
Der effizienteste Weg ist mit dem FOR XML PATH Trick.
Das kam mir nur als eine mögliche Lösung. Ich habe keine Ahnung, wie Leistung, aber ich dachte, es wäre eine interessante Art und Weise, das Problem zu lösen. Getestet habe ich, dass es in einer einfachen Situation funktioniert (ich habe keinen Code für NULL-Werte zu berücksichtigen). Fühlen Sie sich frei, um sich einen Test, um zu sehen, ob es für Sie gut ab.
Die Tabelle, die ich verwendet, enthalten eine ID (my_id). Das könnte wirklich jede Spalte sein, die innerhalb der Gruppe (grp_id) einzigartig ist, so könnte es eine Datumsspalte oder was auch immer sein.
;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