0

我有一个有趣的 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。不,我不能更改数据模型;)。

任何意见是极大的赞赏!

问候,马克

4

2 回答 2

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
于 2009-09-01T22:55:03.120 回答
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;
于 2009-09-02T04:08:58.223 回答