UNPIVOT / PIVOT将多个记录合并为一个

时间:2014-08-20 19:56:52

标签: sql sql-server sql-server-2008 pivot unpivot

目前,我有一个使用下表跟踪产品库存位置的表:

ProductID(PK)  Location(PK) BIN1    BIN2    
  1000             EAST     XRZY    CCAB
  1000             WEST     AAAA    NULL    

我正在尝试将数据移植到以下内容中:

ProductID   EAST_BIN1   EAST_BIN2   WEST_BIN1    WEST_BIN2
  1000        XRZY        CCAB         AAAA         NULL

请注意,位置列已被PIVOT到BIN值字段的一部分。

但是,我发现如果我转动数据,我就无法将它与BIN字段结合起来。 PIVOT只是将BIN值聚合(使用MAX)到一个字段中,而UNPIVOT只是将BIN *字段转换为行。

在转换上述数据方面我缺少什么?

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:2)

您可以“手动”执行以下操作:

SELECT ProductID,
       MAX(CASE WHEN Location='EAST' THEN BIN1 ELSE NULL END) AS EAST_BIN1,
       MAX(CASE WHEN Location='EAST' THEN BIN2 ELSE NULL END) AS EAST_BIN2,
       MAX(CASE WHEN Location='WEST' THEN BIN1 ELSE NULL END) AS WEST_BIN1,
       MAX(CASE WHEN Location='WEST' THEN BIN2 ELSE NULL END) AS WEST_BIN2
FROM YOURTABLE
GROUP BY ProductID

这将创建多行(作为源表),并将结果放在正确的列中,然后使用group by将其粉碎为一行。使用聚合函数MAX获取正确的值。

答案 1 :(得分:0)

要转动您,您需要将数据放入单个BIN列以进行转动。考虑一下......

declare @t table (ProductId int, Location varchar(20), BIN1 varchar(4), BIN2 varchar(4));
insert into @t values(1000, 'EAST', 'XRZY', 'CCAB'), (1000, 'WEST', 'AAAA', null);

with cte as (
    select ProductId, Col = Location + '_BIN1', BINVal = Bin1 from @t
    union all
    select ProductId, Col = Location + '_BIN2', BINVal = Bin2 from @t
)

select
    *
from
    cte
    pivot (
        max(BINVal)
        for Col in ([EAST_BIN1], [EAST_BIN2], [WEST_BIN1], [WEST_BIN2])
    ) p