Sql 如何将行透视到已知最大列数的列

Sql 如何将行透视到已知最大列数的列,sql,sql-server-2008,Sql,Sql Server 2008,我的表格结构如下: 定价组 GroupID | QTY TestGroup1 | 1 TestGroup1 | 2 TestGroup1 | 4 TestGroup1 | 8 TestGroup1 | 22 TestGroup2 | 2 TestGroup3 | 2 TestGroup3 | 5 GroupID | QTY1 | QTY2 | QTY3 | QTY4 | QTY5 T

我的表格结构如下:

定价组

GroupID     |   QTY
TestGroup1  |   1
TestGroup1  |   2
TestGroup1  |   4
TestGroup1  |   8
TestGroup1  |   22
TestGroup2  |   2
TestGroup3  |   2
TestGroup3  |   5
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     |   QTY
TestGroup1  |   1
TestGroup1  |   2
TestGroup1  |   4
TestGroup1  |   8
TestGroup1  |   22
TestGroup2  |   2
TestGroup3  |   2
TestGroup3  |   5
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的一个应用程序,但我不能完全理解这种应用程序所需的语法


谢谢你花时间来研究这件事

您可以围绕生成的排名进行调整

;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

您还可以使用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;

pivot的完美案例,无需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

看起来第一个select语句确定了当数量为5或以上时,排名返回的排名值大于5,尽管总共只有5个值。这些将不会显示在最终透视图中。您可以扩展示例集吗?只有当同一个groupId有>5个不同的值时,它才应该超过5。我需要向导致问题的partitionby语句添加一个额外的键值。我没有提到上面的钥匙,所以你不可能知道。谢谢你的帮助,这真是太棒了!