Объединение / объединение нескольких столбцов уникальных значений в одну строку - PullRequest
0 голосов
/ 27 апреля 2018

Попытка объединить несколько столбцов и строк одним запросом в SSMS. Вот более простая версия более сложной таблицы, с которой я работаю:

Вот мой текущий запрос:

CREATE TABLE Table1
([C1] varchar(50), [C2] varchar(50), [C3] varchar(50))
;

INSERT INTO Table1
([C1], [C2], [C3])
VALUES
('F92', 'Game1', 'b100'),
('F92', 'Game1', 'b200'),
('F92', 'Game2', 'C200'),
('F92', 'Game2', 'D400')
;



SELECT
 C1,C2,
 STUFF(
     (SELECT ', ' + C3
      FROM Table1
      WHERE C1 = a.C1 AND C2 = a.C2
      FOR XML PATH (''))
      , 1, 1, '')  AS NamesList
FROM Table1 AS a
GROUP BY C1,C2

drop table table1

Я намерен получить результат как:

C1   | Namelist
F92  | Game1 b100, b200 Game2 c200, d400

это выполнимо в одном запросе?

Ответы [ 3 ]

0 голосов
/ 27 апреля 2018

Скажите, что значения теперь

 VALUES
('F92', 'Game1', 'b100'),
('F92', 'Game1', 'b200'),
('F92', 'Game2', 'C200'),
('F92', 'Game2', 'D400'),
('F92', 'Game2', 'D500')
;

Итак, теперь Game2 появляется 3 раза. Использование кода кода Шона Ланге было организовано в порядке возрастания, поэтому Game1 появляется перед Game2. Есть ли способ показать результат на основе счетчика столбца c2 (по убыванию), поэтому предполагаемый результат будет

F92 | Game2 C200, D400, D500 Game1 b100, b200 
0 голосов
/ 28 апреля 2018

Расширение на этом примере. Вот новый запрос:

            CREATE TABLE Table1
            ([C1] varchar(50), [C2] varchar(50), [C3] varchar(50),[C4] varchar(50),[C5] varchar(50) )
            ;

            INSERT INTO Table1
            ([C1], [C2], [C3], [C4], [C5])
            VALUES
            ('F92', 'XBOX','81-94','Game1', 'B350'),
            ('F92', 'XBOX','81-94','Game1', 'B150'),
            ('F92', 'XBOX','76-80','Game2', 'PB100'),
            ('F92', 'XBOX','76-80','Game2', 'PB200'),
            ('F92', 'XBOX','95-97','Game2', 'PB300')
            ;

            with FirstPass as
            (
                SELECT
                 C1, c2, 
                    c3 + ' ' + c4+ + STUFF(
                     (SELECT ', ' +''+ c5
                      FROM Table1
                      WHERE C1 = a.C1 AND C2 = a.C2  AND C3 = a.C3  AND C4 = a.C4  
                      FOR XML PATH (''))
                      , 1, 1, '')  AS NamesList
                , count(*) as GameCount
                FROM Table1 AS a
                GROUP BY C1,C2,c3, c4
            )

            select distinct C1,C2
                , NameList = stuff((select ' ' + fp2.NamesList
                    from FirstPass fp2
                    where fp.C1 = fp2.C1
                    group by fp2.GameCount, fp2.NamesList
                    order by fp2.GameCount
                    FOR XML PATH('')), 1, 1, '')
                    into table2
            from FirstPass fp

            -- concatenate and insert into existing table

            insert into table2 (C1, conc)
            select C1, C2 + ' ' + NameList
            from FirstPass fp

            SELECT *  FROM table2


            drop table table1
            drop table table2

Желаемый результат:

C1  |conc
F92 |XBOX 95-97 GAME2 PB300 76-80 GAME2 PB100, PB200 81-94 GAME1 B350, B150

и вставка этого результата в существующую таблицу "table2"

Достигает ли объединение лучшего решения здесь желаемого результата? Эта часть запроса выбивает меня из колеи:

-- concatenate and insert into existing table

            insert into table2 (C1, conc)
            select C1, C2 + ' ' + NameList
            from FirstPass fp
0 голосов
/ 27 апреля 2018

Конечно, вы можете сделать это. Вы можете использовать cte, чтобы получить список с разделителями, который вы уже получаете. Затем возьмите результаты и включите их в другой список с разделителями. Но вам может понадобиться что-то в качестве разделителя между группами, кроме пробела.

with FirstPass as
(
    SELECT
     C1,
     C2 + ' ' + STUFF(
         (SELECT ', ' + C3
          FROM Table1
          WHERE C1 = a.C1 AND C2 = a.C2
          FOR XML PATH (''))
          , 1, 1, '')  AS NamesList
    FROM Table1 AS a
    GROUP BY C1,C2
)

select C1
    , NameList = stuff((select ' ' + fp2.NamesList
        from FirstPass fp2
        where fp.C1 = fp2.C1
        FOR XML PATH('')), 1, 1, '')
from FirstPass fp
group by fp.C1

Возвращает:

F92 | Game1 b100, b200 Game2 C200, D400

- EDIT -

С новыми требованиями к необходимости сортировки C2 по количеству вы можете просто добавить небольшую агрегацию. Это не сильно отличается от оригинала.

with FirstPass as
(
    SELECT
     C1,
     C2 + ' ' + STUFF(
         (SELECT ', ' + C3
          FROM Table1
          WHERE C1 = a.C1 AND C2 = a.C2
          FOR XML PATH (''))
          , 1, 1, '')  AS NamesList
    , count(*) as GameCount
    FROM Table1 AS a
    GROUP BY C1,C2
)

select distinct C1
    , NameList = stuff((select ' ' + fp2.NamesList
        from FirstPass fp2
        where fp.C1 = fp2.C1
        group by fp2.GameCount, fp2.NamesList
        order by fp2.GameCount desc
        FOR XML PATH('')), 1, 1, '')
from FirstPass fp
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...