Вопрос

На этот вопрос уже есть ответ здесь:

Если у меня есть такая таблица:

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

Как я могу получить такой набор результатов:

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

Я знаю, что это действительно легко сделать в MySQL, используя GROUP_CONCAT, но мне нужно сделать это в MSSQL 2005.

Спасибо

(Дубликат Как использовать GROUP BY для объединения строк в SQL Server?)

Это было полезно?

Решение

Для чистого и эффективного решения вы можете создать определяемая пользователем агрегатная функция, есть даже пример это делает именно то, что вам нужно.
Затем вы можете использовать ее как любую другую агрегатную функцию (со стандартным планом запроса):

query plan

Другие советы

Это сделает:

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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top