Say I have purchase and sales data for some SKUs:
po_id | sku | purchase_date | price | qty
----------------------------------------------
1 | 123 | 2013-
setting ambient
declare @purchased table (id int,sku int,dt date,price money,qty int)
declare @sold table (id int,sku int,dt date,price money,qty int)
insert into @purchased
values( 1 , 123 , '2013-01-01 12:25' , 20.15 , 5)
,(2 , 123 , '2013-05-01 15:45' , 17.50 , 3)
,(3 , 123 , '2013-05-02 12:00' , 15.00 , 1)
,(4 , 456 , '2013-06-10 16:00' , 60.00 , 7)
insert into @sold
values(1 , 123 , '2013-01-15 11:00' , 30.00 , 1)
,(2 , 123 , '2013-01-20 14:00' , 28.00 , 3)
,(3 , 123 , '2013-05-10 15:00' , 25.00 , 2)
,(4 , 456 , '2013-06-11 12:00' , 80.00 , 1)
a sqlserver solution should be...
with cte_sold as (select sku,sum(qty) as qty, SUM(qty*price) as total_value
from @sold
group by sku
)
,cte_purchased as (select id,sku,price,qty
from @purchased
union all select id,sku,price,qty-1 as qty
from cte_purchased
where qty>1
)
,cte_purchased_ordened as(select ROW_NUMBER() over (partition by sku order by id,qty) as buy_order
,sku
,price
,1 as qty
from cte_purchased
)
select P.sku
,S.total_value - SUM(case when P.buy_order <= S.qty then P.price else 0 end) as margin
from cte_purchased_ordened P
left outer join cte_sold S
on S.sku = P.sku
group by P.sku,S.total_value,S.qty
resultset achieved
sku margin
123 45,75
456 20,00
same result for sku 123 example in the problem description...
30*1 + 28*3 + 25*2 - 20.15*5 - 17.50*1 = 45.75