Объединить данные в таблице

Вопрос такой

Имеется таблица с данными

id nm dt
111 PP 17 июн 22
111 MM 17 июн 22
111 GG 21 июн 22
222 PP 14 июн 22
222 MM 14 июн 22
222 GG 15 июн 22
333 PP 15 июн 22
333 MM 15 июн 22
333 GG 15 июн 22
444 GG 18 июн 22
555 GG 23 июн 22

Необходимо получить следующее:

id nm dt
111 PP, MM 17 июн 22
111 GG 21 июн 22
222 PP,MM 14 июн 22
222 GG 15 июн 22
333 PP,MM,GG 15 июн 22
444 GG 18 июн 22
555 GG 23 июн 22

По моим прдположениям можно сгруппировать по дате, но как поместить в nm несколько значений при этом не могу понять


Ответы (1 шт):

Автор решения: Vitaliy Zlobin

Если SQL Server 2017 и выше, то:

SELECT  id,
        STRING_AGG(nm,', ') AS nm,
        dt
FROM #tableName
GROUP BY id, dt

Если порядок сгруппированных элементов важен, то так:

STRING_AGG(nm,', ') WITHIN GROUP (ORDER BY nm) AS nm,

До SQL Server 2017 не было функции STRING_AGG, делали так:

SELECT DISTINCT
        id,
        STUFF(( SELECT ', ' + nm
                FROM #tableName tt
                WHERE t.id = tt.id AND t.dt = tt.dt
                FOR XML PATH ('')), 1, 1, '') AS nm,
        dt
FROM #tableName AS t

Для проверки:

SELECT *
INTO #tableName
FROM
(
    VALUES
    (111,   'PP',   '17 июн 22'),
    (111,   'MM',   '17 июн 22'),
    (111,   'GG',   '21 июн 22'),
    (222,   'PP',   '14 июн 22'),
    (222,   'MM',   '14 июн 22'),
    (222,   'GG',   '15 июн 22'),
    (333,   'PP',   '15 июн 22'),
    (333,   'MM',   '15 июн 22'),
    (333,   'GG',   '15 июн 22'),
    (444,   'GG',   '18 июн 22'),
    (555,   'GG',   '23 июн 22')
) AS T(id, nm, dt)
→ Ссылка