我有一个有趣的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上搜索。不,我无法更改数据模型;)。
非常感谢任何建议!
此致 标记
答案 0 :(得分: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
答案 1 :(得分: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;