2011-03-21 4 views
1

どのくらいアイテムが消費された(消耗した)かを計算するためにクエリを実行するにはどうすればよいですか?SQL量がクエリを消費しましたか?

私たちは列ID、のProductIdで購入テーブルで購入各アイテムの数量を見つけることができ、数量(10進数)、日付

Id, ProductId, Qty, Date  
1, 1,   10, 1/1/11 
2, 1,   5, 2/2/11 
3, 1,   8, 3/3/11 

そして、どのようにあなたは、その後のどのように多くの数を追加します購入テーブルの各行が消費されました。厳密なFIFOを前提としていますか?したがって、上記の例では、我々が消費されている14の出力が可能だろうとわかっている場合:

Id, ProductId, Qty, Date, Consumed  
1, 1,   10, 1/1/11, 10 
2, 1,   5, 2/2/11, 4 
3, 1,   8, 3/3/11, 0 

うまくいけば、私は量消費クエリによって何を意味するかを説明している - 私たちは14が消費された知っていて、最初の購入が10のためだったことしたがって、10個すべてが消費されています。次回の購入は5件だったので、それらのうち4件が消費されたことがわかりました。列のProductId、QtyUsed(これはConsumedItems.QtyUsedの和である)

とID、のProductId、QtyUsed、日付)、またはConsumedSummaryViewから列:ConsumedItemsテーブル - 私はから消費データを取得することができる2つの場所Theresの

答えて

2

リチャードさんよりも少し異なるアプローチが、私はより良い実行されますかわからないんだけど:非常に近いのです

SELECT 
    Purchases.Id, 
    Purchases.ProductId, 
    Purchases.Qty, 
    Purchases.Date, 
    CASE 
     WHEN COALESCE (PreviousPurchases.PreviousUsed, 0) + Qty < ConsumedSummaryView.QtyUsed THEN Qty 
     ELSE 
      CASE 
       WHEN ConsumedSummaryView.QtyUsed - COALESCE (PreviousPurchases.PreviousUsed, 0) < 0 THEN 0 
       ELSE ConsumedSummaryView.QtyUsed - COALESCE (PreviousPurchases.PreviousUsed, 0) 
      END 
    END AS Used 
FROM 
    Purchases 
    INNER JOIN ConsumedSummaryView ON Purchases.ProductId = ConsumedSummaryView.ProductId 
    LEFT OUTER JOIN (
     SELECT 
      SUM(Purchases_2.Qty) AS PreviousUsed, 
      Purchases_1.Id 
     FROM 
      Purchases AS Purchases_2 
      INNER JOIN Purchases AS Purchases_1 ON Purchases_2.Id < Purchases_1.Id 
               AND Purchases_2.ProductId = Purchases_1.ProductId 
     GROUP BY 
      Purchases_1.Id 
    ) AS PreviousPurchases ON Purchases.Id = PreviousPurchases.Id 
+0

うまくいかないようですか?私はUsed = 10、NULL、3行(上記の@Richardテストデータ設定スクリプト+上記のクエリを使用して)を返します –

+1

残念ながら、そこに変数を残しました。やってみよう。 –

+0

あなたのソリューションは今のところよく見ています –

5

サンプルテーブルやビュー

create table purchases (Id int, ProductId int, Qty int, Date datetime) 
insert purchases select 1, 1,   10, '1/1/11' 
insert purchases select 2, 1,   5, '2/2/11' 
insert purchases select 3, 1,   8, '3/3/11' 
create view ConsumedSummaryView as select ProductID = 1, QtyUsed = 14 

クエリ

;with p as (
    select *, rn=ROW_NUMBER() over (partition by productid order by date, id) 
    from purchases) 
, tmp(Id, ProductId, Qty, Date, rn, ToGo, Consumed) as (
    select p.Id, p.ProductId, p.Qty, p.Date, cast(1 as bigint), 
      CAST(ISNULL(v.qtyused,0) - p.Qty as decimal(20,10)), 
     cast(case 
      when v.qtyused >= p.Qty Then p.Qty 
      when v.qtyused > 0 then v.qtyused 
      else 0 end as decimal(20,10)) 
    from p 
    left join ConsumedSummaryView v on p.ProductId = v.productId 
    where rn=1 
    union all 
    select p.Id, p.ProductId, p.Qty, p.Date, cast(p.rn as bigint), 
      cast(ISNULL(tmp.toGo,0) - p.Qty as decimal(20,10)), 
     cast(case 
      when tmp.toGo >= p.Qty Then p.Qty 
      when tmp.toGo > 0 then tmp.toGo 
      else 0 end as decimal(20,10)) 
    from tmp 
    --inner join p on p.rn=tmp.rn+1 
    inner join p on p.rn=tmp.rn+1 and p.productid = tmp.ProductId 
) 
select Id, ProductId, Qty, Date, Consumed 
from tmp 
order by rn 

出力

Id   ProductId Qty   Date     Consumed 
----------- ----------- ----------- ----------------------- ----------- 
1   1   10   2011-01-01 00:00:00.000 10 
2   1   5   2011-02-02 00:00:00.000 4 
3   1   8   2011-03-03 00:00:00.000 0 
+0

感謝。しかし、Qtyは10進数であると言っていることを忘れました。あなたのソリューションにこのエラーがあります。再帰クエリ "tmp"の "ToGo"列のアンカーと再帰部分の型が一致しません " –

+0

上記のサンプルテーブルを' create table purchases(ID int、ProductId int 、Qty decimal、Date datetime) 'エラーが発生したことを確認することができます –

+0

@JK疑問がある場合は、再帰CTEの両方の部分をCASTで更新しました。 20,10からもっと妥当なものに小数点を切り捨てる – RichardTheKiwi

関連する問題