SQL Server高级Pivot将行分组到列

时间:2017-10-07 17:34:22

标签: sql sql-server sql-server-2008 pivot dense-rank

我需要将行中的数据旋转/旋转到列中 - 但与我见过的大多数示例略有不同。

我们的顾客会买套装(想想披萨原料卖家......人们总是会买奶酪,面团和酱汁;有些人会购买配料,但我们并不关心)。

我需要做的是按行订单日期将此行数据排序到列中。下面是两个填充临时输入和临时输出表的脚本,以显示我正在尝试实现的目标。

SQL Server 2008

CREATE table #myInput
    (CustomerID Varchar(10), OrderDate varchar(10), Item varchar(13), ItemColor varchar(20));


CREATE table #myOUTPUT
    (
    CustomerID Varchar(10), 
    OrderDate_1 varchar(10), 
    PartA_1 varchar(20), 
    PartB_1 varchar(20),
    PartC_1 varchar(20),
    OrderDate_2 varchar(10), 
    PartA_2 varchar(20), 
    PartB_2 varchar(20),
    PartC_2 varchar(20),
    OrderDate_3 varchar(10), 
    PartA_3 varchar(20), 
    PartB_3 varchar(20),
    PartC_3 varchar(20)
    )
INSERT INTO #myInput
    (CustomerID, OrderDate, Item, ItemColor)
VALUES
('abc','5/1/2001','PartA','Silver'),
('abc','5/1/2001','PartB','Red'),
('abc','5/1/2001','PartC','Green'),
('abc','5/20/2002','PartA','Purple'),
('abc','5/20/2002','PartB','Yellow'),
('abc','5/20/2002','PartC','Black'),
('abc','10/1/2002','PartA','Red'),
('abc','10/1/2002','PartB','Silver'),
('abc','10/1/2002','PartC','Blue'),
('def','4/1/2000','PartA','Green'),
('def','4/1/2000','PartB','Red'),
('def','4/1/2000','PartC','White'),
('jkl','5/1/2001','PartA','Black'),
('jkl','5/1/2001','PartB','Yellow'),
('jkl','5/1/2001','PartC','Silver'),
('jkl','10/10/2001','PartA','Green'),
('jkl','10/10/2001','PartB','Black'),
('jkl','10/10/2001','PartC','Silver')
;

结果:

insert into #myOUTPUT 

(客户ID,OrderDate_1,PartA_1,PartB_1,PartC_1,OrderDate_2,PartA_2,PartB_2,PartC_2,OrderDate_3,PartA_3,PartB_3,PartC_3)

VALUES 
('abc','5/1/2001','Silver','Red','Green','5/20/2002','Purple','Yellow','Black','10/1/2002','Red','Silver','Blue'),
('def','4/1/2000','Green','Red','White','','','','','','','',''),
('jkl','5/1/2001','Black','Yellow','Silver','10/10/2001','Green','Black','Silver','','','','');

select * from #myInput
select * from #myOUTPUT

我们正在寻找17个或更少的订单。至少在目前,我们没有为任何一个客户提供超过十几个订单。

我尝试了几个不同的东西 - 枢轴似乎没有产生我正在寻找的输出。我想也许dense_rank可以确定我们首先需要多少列,然后通过cte插入游标句柄?但我无法得到所需的输出。请注意,源“date”字段作为varchar存储在DB中。此外,没有订单号 - 所以非常不仅仅来自客户ID和日期。

1 个答案:

答案 0 :(得分:1)

我会使用条件聚合来解决这个问题。如果我理解正确:

select customer,
       max(case when seqnum_co = 1 then orderdate end) as orderdate_1,
       max(case when seqnum_co = 1 and item = 'Part_A' then itemcolor end) as parta_1,
       max(case when seqnum_co = 1 and item = 'Part_B' then itemcolor end) as partb_1,
       max(case when seqnum_co = 1 and item = 'Part_C' then itemcolor end) as partc_1,
       max(case when seqnum_co = 2 then orderdate end) as orderdate_2,
       max(case when seqnum_co = 2 and item = 'Part_A' then itemcolor end) as parta_2,
       max(case when seqnum_co = 2 and item = 'Part_B' then itemcolor end) as partb_2,
       max(case when seqnum_co = 2 and item = 'Part_C' then itemcolor end) as partc_2,
       . . .
from (select i.*,
             dense_rank() over (partition by i.customerid order by orderdate) as seqnum_co
      from #myinput
     ) i
group by customer;