如何使用SQL Server制作具有相同列名的两个透视列?

时间:2017-08-10 06:38:24

标签: sql sql-server stored-procedures pivot

我想使用具有相同列的聚合函数创建两个透视列。

ItemLookupCode    StoreID    DepartmentID    Weeks        QtySold   AsOfWeekOnHand
----------------------------------------------------------------------------------
610759C2000        1001        23             30             0         1.5
610759C2000        1001        23             31             0          0
610759C2000        1004        23             30             0          2
610759C2000        1004        23             31             0         3.5 
610759C2000        1201        23             30           0.6395       1
610759C2000        1201        23             31           0.6395       2

我尝试使用以下查询。但这是错的。什么是正确的方法?

select itemlookupcode, storeid, departmentid,[30],[31] from 
(
    select 
        fr.itemlookupcode,
        fr.storeid,
        fr.departmentid,
        fr.asofweekonhand,
        fr.weeks,
        fr.QtySold
    from 
        #finalresult fr
) x
pivot 
(
    sum(QtySold)
    for weeks in ([30],[31])
) p1 
pivot 
(
    sum(asofweekonhand)
    for weeks in ([30],[31])
) p2 

注意

  

我们可以将列名指定为

Week30Sold    Week31Sold    Week30AsOfWeekOnHand    Week31AsOfWeekOnHand
-------------------------------------------------------------------------

1 个答案:

答案 0 :(得分:1)

我认为这大致符合您的要求:

declare @t table (ItemLookupCode varchar(20), StoreID int, DepartmentID int, Weeks int,
                  QtySold decimal(10,4), AsOfWeekOnHand decimal(10,4))
insert into @t(ItemLookupCode,StoreID,DepartmentID,Weeks,QtySold,AsOfWeekOnHand) values
('610759C2000',1001,23,30,  0   ,1.5 ),
('610759C2000',1001,23,31,  0   , 0  ),
('610759C2000',1004,23,30,  0   , 2  ),
('610759C2000',1004,23,31,  0   ,3.5 ),
('610759C2000',1201,23,30,0.6395, 1  ),
('610759C2000',1201,23,31,0.6395, 2  )

select
    *
from
    (select ItemLookupCode,StoreID,DepartmentID,
      CONVERT(varchar(13),Weeks) + 'Qty' as Weeks,
      QtySold from @t) t1
    pivot (SUM(QtySold) for Weeks in ([30Qty],[31Qty])) p1
    cross apply
    (select CONVERT(varchar(13),Weeks) + 'AsOf' as Weeks,AsOfWeekOnHand
    from @t t2
    where t2.ItemLookupCode = p1.ItemLookupCode and
    t2.DepartmentID = p1.DepartmentID and
    t2.StoreID = p1.StoreID) t2
    pivot (SUM(AsOfWeekOnHand) for Weeks in ([30AsOf],[31AsOf])) p2

结果:

ItemLookupCode       StoreID     DepartmentID 30Qty      31Qty    30AsOf   31AsOf
-------------------- ----------- ------------ ---------- -------- -------- -------
610759C2000          1001        23           0.0000     0.0000   1.5000   0.0000
610759C2000          1004        23           0.0000     0.0000   2.0000   3.5000
610759C2000          1201        23           0.6395     0.6395   1.0000   2.0000

值得注意的是:

  • 您不能使用相同的列进行两次转动 - 在转轴之后,pivot子句第一部分中提到的列不再存在,已被括号中的新列名替换。

  • 我们必须对子查询执行apply而不是JOIN以避免引入重复的列(例如,ItemLookupCode会出现两次如果t2是子查询的join,则结果集

  • 我借此机会重命名子查询中的Weeks

  • 当我们使用APPLY时,我们必须使用p1作为外部引用 - PIVOT生成一个全新的结果集,用于替换任何现有的结果集/别名。

  • 正如my answer to your earlier question中所述,PIVOT有效GROUP BY PIVOT条款中未提及的所有列 - 所以为什么不列?由第一个PIVOT在第二个枢纽期间产生的关注?因为我们已经知道ItemLookupCodeStoreIDDepartmentID的每个组合本身都是唯一的,因为第一个PIVOT