Как повернуть строки в столбцы с известным максимальным количеством столбцов - PullRequest
3 голосов
/ 14 декабря 2011

У меня есть таблица, структурированная так:

Pricing_Group

GroupID     |   QTY
TestGroup1  |   1
TestGroup1  |   2
TestGroup1  |   4
TestGroup1  |   8
TestGroup1  |   22
TestGroup2  |   2
TestGroup3  |   2
TestGroup3  |   5

То, что я ищу, это результат, подобный следующему:

Pricing_Group

GroupID     |   QTY1    |   QTY2    |   QTY3    |   QTY4    |   QTY5
TestGroup1  |   1       |   2       |   4       |   8       |   22
TestGroup2  |   2       |   NULL    |   NULL    |   NULL    |   NULL
TestGroup3  |   2       |   5       |   NULL    |   NULL    |   NULL

Обратите внимание, что для данного идентификатора GroupID может быть только максимум 5 разных величин, просто неизвестно, какими будут эти 5 величин.

Это похоже на приложение PIVOT, но я не могу полностью разобраться с синтаксисом, который потребуется для такого приложения.

Спасибо, что нашли время, чтобы разобраться в этом!

Ответы [ 3 ]

4 голосов
/ 14 декабря 2011

Идеальный кейс для разворота, и вам не нужен CTE:

Declare @T Table (GroupID varchar(10) not null,
    QTY int)

Insert Into @T
Values ('TestGroup1', 1),
    ('TestGroup1', 2),
    ('TestGroup1', 4),
    ('TestGroup1', 8),
    ('TestGroup1', 22),
    ('TestGroup2', 2),
    ('TestGroup3', 2),
    ('TestGroup3', 5)

Select GroupID, [QTY1], [QTY2], [QTY3], [QTY4], [QTY5]
From (Select GroupID, QTY, 
    RowID = 'QTY' + Cast(ROW_NUMBER() Over (Partition By GroupID Order By QTY) as varchar)
    from @T) As Pvt
Pivot (Min(QTY)
    For RowID In ([QTY1], [QTY2], [QTY3], [QTY4], [QTY5])
    ) As Pvt2
3 голосов
/ 14 декабря 2011

Вы можете поворачиваться на сгенерированный ранг;

;with T as (
    select
        rank() over (partition by GroupID order by GroupID, QTY) as rank,
        GroupID, 
        QTY
    from
        THE_TABLE
)
select 
    * 
from 
    T
pivot (
    max(QTY) 
    for rank IN ([1],[2],[3],[4],[5])
) pvt

>> 
GroupID     1     2     3     4     5
----------------------------------------
TestGroup1  1     2     4     8     22
TestGroup2  2     NULL  NULL  NULL  NULL
TestGroup3  2     5     NULL  NULL  NULL
1 голос
/ 14 декабря 2011

Вы также можете использовать оператор case для выполнения сводки:

declare @t table ( GroupID varchar(25), QTY int)
insert into @t
    values  ('TestGroup1', 1),
            ('TestGroup1', 2),
            ('TestGroup1', 4),
            ('TestGroup1', 8),
            ('TestGroup1', 22),
            ('TestGroup2', 2),
            ('TestGroup3', 2),
            ('TestGroup3', 5)

;with cte_Stage (r, GroupId, QTY)
as  (   select  row_number() over(partition by GroupId order by QTY ),
                GroupId,
                QTY
        from    @t
    )
select  GroupId,
        [QTY1] = sum(case when r = 1 then QTY else null end),
        [QTY2] = sum(case when r = 2 then QTY else null end),
        [QTY3] = sum(case when r = 3 then QTY else null end),
        [QTY4] = sum(case when r = 4 then QTY else null end),
        [QTY5] = sum(case when r = 5 then QTY else null end),
        [QTYX] = sum(case when r > 5 then QTY else null end)
from    cte_Stage
group
by      GroupId;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...