2009-09-01 48 views
0

我有一个有趣的SQL问题,我需要帮助。帮助SQL - 将两行合并为一行

下面是示例数据集:

Warehouse DateStamp TimeStamp ItemNumber ID 
    A  8/1/2009 10001   abc  1 
    B  8/1/2009 10002   abc  1 
    A  8/3/2009 12144   qrs  5 
    C  8/3/2009 12143   qrs  5 
    D  8/5/2009 6754   xyz  6 
    B  8/5/2009 6755   xyz  6 

该数据集表示两个仓库之间库存转移。有两个记录表示每次传输,并且这两个传输记录始终具有相同的ItemNumber,DateStamp和ID。两个转移记录的TimeStamp值始终有差值1,其中较小的TimeStamp表示源仓库记录,较大的TimeStamp表示目标仓库记录。

使用上面的样本数据集,这里是查询结果集,我需要:

Warehouse_Source Warehouse_Destination ItemNumber DateStamp 
    A    B      abc  8/1/2009 
    C    A      qrs  8/3/2009 
    D    B      xyz  8/5/2009 

我可以编写代码来生成所需的结果集,但我想知道如果这个记录相结合,通过SQL是可能的。我使用SQL Server 2005作为我的底层数据库。我还需要为SQL添加WHERE子句,例如,我可以在Warehouse_Source = A上进行搜索。不,我不能更改数据模型;)。

任何意见非常感谢!

问候, 马克

回答

7
SELECT source.Warehouse as Warehouse_Source 
, dest.Warehouse as Warehouse_Destination 
, source.ItemNumber 
, source.DateStamp 
FROM table source 
JOIN table dest ON source.ID = dest.ID 
    AND source.ItemNumber = dest.ItemNumber 
    AND source.DateStamp = dest.DateStamp 
    AND source.TimeStamp = dest.TimeStamp + 1 
+0

完美!谢谢... – 2009-09-04 23:03:35

0

马克,

这里是你如何与ROW_NUMBER和PIVOT做到这一点。在我建议的列上使用聚簇索引或主键时,它将使用不带排序操作的直线查询计划,因此效率特别高。

create table T(
    Warehouse char, 
    DateStamp datetime, 
    TimeStamp int, 
    ItemNumber varchar(10), 
    ID int, 
    primary key(ItemNumber,DateStamp,ID,TimeStamp) 
); 
insert into T values ('A','20090801','10001','abc','1'); 
insert into T values ('B','20090801','10002','abc','1'); 
insert into T values ('A','20090803','12144','qrs','5'); 
insert into T values ('C','20090803','12143','qrs','5'); 
insert into T values ('D','20090805','6754','xyz','6'); 
insert into T values ('B','20090805','6755','xyz','6'); 

with Tpaired(Warehouse,DateStamp,TimeStamp,ItemNumber,ID,rk) as (
    select 
    Warehouse,DateStamp,TimeStamp,ItemNumber,ID, 
    row_number() over (
     partition by ItemNumber,DateStamp,ID 
     order by TimeStamp 
    ) 
    from T 
) 
    select 
    max([1]) as Warehouse_Source, 
    max([2]) as Warehouse_Destination, 
    ItemNumber, 
    DateStamp 
    from Tpaired 
    pivot (
    max(Warehouse) for rk in ([1],[2]) 
) as P 
    group by ItemNumber, DateStamp, ID; 
go 

drop table T;