Reputation: 65
I am trying to find out differences between two rows in a same table. Having trouble to find right query. For example, I have
Year Item Qty Amount
------------------------------
2014 Shoes 500 2500
2014 Ties 300 900
2014 Pants 200 4000
2015 Shoes 600 3000
2015 Ties 200 600
I am trying to find out what was the increased (or decreased) from previous year to this year. I will always have only two years to compare. The query result should look like following:
Items Qty Diff Amount Diff
------------------------------
Shoes 100 500
Ties (-100) (-300)
Pants Null Null
What should be the query look like?
Upvotes: 2
Views: 165
Reputation: 91
Here is the required query:
SET @YEAR1 = '2014';
SET @YEAR2 = '2015';
SELECT
Item,
if(count(*)>1,sum(if(Year=@YEAR2,Qty,-Qty)),NULL) as 'Qty Diff',
if(count(*)>1,sum(if(Year=@YEAR2,Amount,-Amount)),NULL) as 'Amount Diff'
FROM
table
WHERE
Year IN (@YEAR1,@YEAR2)
group by Item;
Upvotes: 0
Reputation: 716
Using the lag function is the best approach to this.
SELECT [Year], [Item], [Qty], [Amount],
[Qty] - LAG([Qty]) OVER (PARTITION BY [Item] ORDER BY [Year]) [QtyDiff],
[Amount] - LAG([Amount]) OVER (PARTITION BY [Item] ORDER BY [Year]) [AmountDiff]
FROM [ItemTable] it
order BY [Year] DESC, [Item];
Hope this helps.
Upvotes: 1
Reputation: 2328
1. Use LAG or LEAD
WITH tb(Year,Item,Qty,Amount) AS (
SELECT 2014,'Shoes',500,2500 UNION
SELECT 2014,'Ties',300,900 UNION
SELECT 2014,'Pants',200,4000 UNION
SELECT 2015,'Shoes',600,3000 UNION
SELECT 2015,'Ties',200,600
)
SELECT *,Qty-LAG(qty)OVER(PARTITION BY Item ORDER BY year) AS QtyDiff ,Amount-LAG(Amount)OVER(PARTITION BY Item ORDER BY year) AS AmountDiff
FROM tb
Year Item Qty Amount QtyDiff AmountDiff ----------- ----- ----------- ----------- ----------- ----------- 2014 Pants 200 4000 NULL NULL 2014 Shoes 500 2500 NULL NULL 2015 Shoes 600 3000 100 500 2014 Ties 300 900 NULL NULL 2015 Ties 200 600 -100 -300
2.Cross or Outer Apply
WITH tb(Year,Item,Qty,Amount) AS (
SELECT 2014,'Shoes',500,2500 UNION
SELECT 2014,'Ties',300,900 UNION
SELECT 2014,'Pants',200,4000 UNION
SELECT 2015,'Shoes',600,3000 UNION
SELECT 2015,'Ties',200,600
)
SELECT t1.Year,t1.Item,t1.Qty- t2.qty AS DiffQty,t1.Amount-t2.Amount AS DiffAmount
FROM tb AS t1
OUTER APPLY (SELECT TOP 1 tt.qty,tt.Amount FROM tb AS tt WHERE tt.Year<t1.Year AND t1.Item=tt.Item ORDER BY tt.Year desc) AS t2
ORDER BY t1.Item,t1.Year
Upvotes: 2
Reputation: 3127
If you want to include everything, then you can use FULL OUTER JOIN
, if just the one with the earlier year, LEFT OUTER JOIN
, if you want the one with both earlier and subsequent year, then INNER JOIN
.
SELECT
T1.Item
, (T2.QTY-T1.QTY) AS [QTY Diff]
, (T2.Amount - T1.Amount) AS [Amount Diff]
FROM
<<Table>> T1
LEFT OUTER JOIN <<Table>> T2
ON T1.Item=T2.Item
AND T1.YEAR=(T2.YEAR-1);
Upvotes: 5