2011-03-21 8 views
1

얼마나 많은 항목을 소비했는지 계산하기 위해 쿼리를 어떻게 사용합니까?SQL 사용량 쿼리가 필요합니까?

우리는 이드, 제품 ID, 수량 (진수), 날짜

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 개가 소비되었음을 알았습니다.

Theres는 두 곳에 내가 할 수있는 소비 데이터로부터 얻을 - ConsumedItems 테이블 : 열 이드, 제품 ID, QtyUsed, 날짜), 또는 열 제품 ID와 ConsumedSummaryView에서 QtyUsed (이 ConsumedItems.QtyUsed의 합)

답변

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

작동하지 않는 것 같습니까? 나는 = 10, NULL, 3 행에 대해 0을 사용합니다. @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의 두 부분을 모두 캐스팅했습니다. 십진법을 20,10에서 좀 더 합리적으로 바꾸십시오. – RichardTheKiwi

관련 문제