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

このデータセットは、2 つの倉庫間の在庫移動を表しています。各転送を表す 2 つのレコードがあり、これら 2 つの転送レコードは常に同じ ItemNumber、DateStamp、および ID を持ちます。2 つの転送レコードの 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 を使用してこれを行う方法です。私が提案するように、列にクラスター化されたインデックスまたは主キーを使用すると、Sort 操作のない直線的なクエリ プランが使用されるため、特に効率的です。

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 に答える