2016-09-01 12 views
0

私はこのようになりますdbo.StockLocationHistoryTableいる:前提は、従業員がストック・テイクを行うたびに、行がその製品のために追加されていることをSQL証券の追跡

SELECT * FROM dbo.StockLocationHistory AS slh  

    StockIdentifier | DateScanned    | WarehouseLocation 
    ------------------------------------------------- 
    72825   | 2016-07-03 16:41:24.077 | 854 
    30509   | 2016-07-03 16:41:24.077 | 854 
    30509   | 2016-07-05 08:22:10.056 | 854 
    30509   | 2016-07-06 14:22:15.099 | 628 
    30509   | 2016-07-08 15:28:22.542 | 628 
    72825   | 2016-07-08 15:32:25.256 | 778 
    30509   | 2016-07-10 18:22:24.556 | 854 

ですし、場所は製品があります上記の表から、製品72825はロケーション854の3番目にスキャンされ、次にロケーション778の8番目にスキャンされたことがわかります。

残念ながら、ソフトウェアはそれを検出するとStockOUTレコードに入れません製品は以前のスキャンとは別の場所にあります。私は(成功裏に)場所の歴史を詳述する場所帳を作成しようとしています。

暫定スキャン(EG:最初のコードブロックの行3)ではなく、在庫が場所に追加され、場所から削除されたときのみに関係します。在庫が新しい場所でStockOUTイベントとして検出されたときに、コードブロック2に示すように詳細を表示する必要もあります。私は必要なもの

は以下の通りです:

DECLARE @WarehouseLocation INT = 854 

[DateScanned]   | StockIdentifier | EventType | StockLevel 
------------------------------------------------------------------ 
2016-07-03 16:41:24.077 | 30509   | StockIN | 1 
2016-07-03 16:41:24.077 | 72825   | StockIN | 2 
2016-07-06 14:22:15.099 | 30509   | StockOUT | 1 
2016-07-08 15:32:25.256 | 72825   | StockOUT | 0 
2016-07-10 18:22:24.556 | 30509   | StockIN | 1 

答えて

0

私は非常にあなたがこれらのデータを取得する他の方法を考えることをお勧めします。その理由は、SQLは複雑になり、私の意見ではそれほど効果的ではないということです。構造やテーブル処理の変更について考えることができます。

もしそうでなければ、おそらくStockLevelを数えることは、アプリケーションレベルで(中間テーブルを必要としないで)行う方が簡単でしょう。

ターゲットテーブルの名前が@tに変更され、コードが小さくなります。 StockLevelを正しくカウントするために導入された "@ intermediate.id"(DateScannedは一意ではないため) 最後の "ORDER BY"は正しい順序を保証することです( "GROUP BY"はすべてのケースでこれを保証しないためです)。

declare @WarehouseLocation int = 854 

declare @intermediate table(id int identity primary key, DateScanned datetime, StockIdentifier int, EventType char(8)) 

insert @intermediate 
select tin.DateScanned, tin.StockIdentifier, 'StockIN' as EventType from @t tin 
    where tin.WarehouseLocation = @WarehouseLocation 
    and not exists(select * from @t t 
     where t.StockIdentifier = tin.StockIdentifier 
     and t.WarehouseLocation = @WarehouseLocation 
     and t.DateScanned < tin.DateScanned 
     and not exists(select * from @t tout 
      where tout.StockIdentifier = t.StockIdentifier 
      and tout.DateScanned > t.DateScanned and tout.DateScanned < tin.DateScanned 
      and tout.WarehouseLocation != @WarehouseLocation)) 
union all 
select tout.DateScanned, tout.StockIdentifier, 'StockOUT' as EventType from @t tout 
    where tout.WarehouseLocation != @WarehouseLocation 
    and not exists(select * from @t t 
     where t.StockIdentifier = tout.StockIdentifier 
     and t.WarehouseLocation != @WarehouseLocation 
     and t.DateScanned < tout.DateScanned 
     and not exists(select * from @t tin 
      where tin.StockIdentifier = t.StockIdentifier 
      and tin.DateScanned > t.DateScanned and tin.DateScanned < tout.DateScanned 
      and tin.WarehouseLocation = @WarehouseLocation)) 
order by DateScanned 

select t.DateScanned, t.StockIdentifier, t.EventType, 
    sum(case when prev.EventType = 'StockIn' then 1 else -1 end) as StockLevel 
from @intermediate t left join @intermediate prev on prev.id <= t.id 
group by t.DateScanned, t.StockIdentifier, t.EventType 
order by t.DateScanned 
関連する問題