Группы Concat в SQL Server [дубликат]
-
06-09-2019 - |
Вопрос
На этот вопрос уже есть ответ здесь:
Если у меня есть такая таблица:
+------------+
| Id | Value |
+------------+
| 1 | 'A' |
|------------|
| 1 | 'B' |
|------------|
| 2 | 'C' |
+------------+
Как я могу получить такой набор результатов:
+------------+
| Id | Value |
+------------+
| 1 | 'AB' |
|------------|
| 2 | 'C' |
+------------+
Я знаю, что это действительно легко сделать в MySQL, используя GROUP_CONCAT, но мне нужно сделать это в MSSQL 2005.
Спасибо
(Дубликат Как использовать GROUP BY для объединения строк в SQL Server?)
Решение
Для чистого и эффективного решения вы можете создать определяемая пользователем агрегатная функция, есть даже пример это делает именно то, что вам нужно.
Затем вы можете использовать ее как любую другую агрегатную функцию (со стандартным планом запроса):
Другие советы
Это сделает:
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
Часто спросил здесь.
Самый эффективный способ — использовать трюк FOR XML PATH.
Это просто пришло мне в голову как одно из возможных решений.Я понятия не имею о производительности, но подумал, что это будет интересный способ решить проблему.Я проверил, что это работает в простой ситуации (я не писал код для учета NULL).Не стесняйтесь протестировать его, чтобы убедиться, что он работает хорошо для вас.
Таблица, которую я использовал, включала идентификатор (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