Reputation: 1473
I was able to group the item counts three years prior and three years after on certain date, but I was not able to break the item counts in three separate years.
SELECT
ITEM,
CASE WHEN DATE >='12/6/02' AND DATE <'12/6/05' AND ITEM ='RICE' THEN 'RICE PRIOR'
CASE WHEN DATE >='12/06/05' AND DATE <'12/6/08' AND ITEM ='RICE' THEN 'RICE POST'
END AS TYPE,
COUNT (QTY) AS RICE
FROM #TEMP
WHERE DATE >='12/6/02'
AND DATE <'12/6/08'
GROUP BY ITEM,
CASE WHEN DATE >='12/6/02' AND DATE <'12/6/05' AND ITEM ='RICE' THEN 'RICE PRIOR'
CASE WHEN DATE >='12/06/05' AND DATE <'12/6/08' AND ITEM ='RICE' THEN 'RICE POST'
END
How can I break it down into three years? Running this script, my result shows:
Type, Rice
Rice Prior 444
Rice Post 555
My desired output would be something like:
Year3, Year2, Year1 Year1, Year2, Year3
4 44 400 5 500 50
Upvotes: 1
Views: 174
Reputation: 13179
This should match your desired query using a pivot and date parameter so you don't have to hard code it all the dates and conditions.
DECLARE @Date DATE = '12/6/2005'
SELECT
ITEM,
[-3] AS Year3,
[-2] AS Year2,
[-1] AS Year1,
[1] AS Year1,
[2] AS Year2,
[3] AS Year3
FROM (
SELECT
ITEM,
DATEDIFF(DD, @Date, [DATE]) / 365
+ CASE WHEN @Date < [DATE] THEN 1 ELSE -1 END AS [YR],
QTY
FROM #TEMP
) T
PIVOT (MAX(QTY) FOR [YR] IN ([-3], [-2], [-1], [1], [2], [3])) PVT
The above approach does not account for leap years. You can apply @JPW's approach of using DATEADD
which is aware of leap years. You'll just need to be aware of the border scenarios of which is the first and last day of each region. In this approach, the first match wins, so today's date would be in year "-1".
DECLARE @D DATE = '12/6/2005'
SELECT
ITEM,
[-3] AS Year3,
[-2] AS Year2,
[-1] AS Year1,
[1] AS Year1,
[2] AS Year2,
[3] AS Year3
FROM (
SELECT
ITEM,
CASE
WHEN DATE BETWEEN DATEADD(YEAR, -3, @D) AND DATEADD(YEAR, -2, @D) THEN -3
WHEN DATE BETWEEN DATEADD(YEAR, -2, @D) AND DATEADD(YEAR, -1, @D) THEN -2
WHEN DATE BETWEEN DATEADD(YEAR, -1, @D) AND DATEADD(YEAR, -0, @D) THEN -1
WHEN DATE BETWEEN DATEADD(YEAR, +0, @D) AND DATEADD(YEAR, +1, @D) THEN 1
WHEN DATE BETWEEN DATEADD(YEAR, +1, @D) AND DATEADD(YEAR, +2, @D) THEN 2
WHEN DATE BETWEEN DATEADD(YEAR, +2, @D) AND DATEADD(YEAR, +3, @D) THEN 3
ELSE NULL END AS [YR],
QTY
FROM #TEMP
) T
PIVOT (MAX(QTY) FOR [YR] IN ([-3], [-2], [-1], [1], [2], [3])) PVT
Upvotes: 2
Reputation: 17126
So basically you can apply your count logic inside the select portion of PIVOT and then pivot the result set on years
SELECT ITEM, [2002] AS[Year-3],[2003] AS [Year-2], [2004] AS [Year-1],
[2005] AS [Year1],[2006] AS [Year2],[2007] AS [Year3]
FROM (
-- Your logic here
SELECT
ITEM,
YEAR(Date) as Y,
COUNT (quantity) AS RICE
FROM [dbo].[temp]
WHERE DATE >='12/6/01'
AND DATE <'12/6/08'
GROUP BY ITEM,YEAR(Date)
) as s
PIVOT
(
SUM(RICE)
FOR Y IN ([2002], [2003], [2004], [2005],[2006],[2007])
)AS p
Sql fiddle link http://sqlfiddle.com/#!6/fa406/2
Upvotes: 0
Reputation: 44881
Based on your sample output I think a query like below might be what you want. You might have to tweak the date ranges to fit your needs but the general idea should be clear:
DECLARE @d date = '2005-07-27';
WITH cte AS
(
SELECT
ITEM
, SUM(CASE WHEN DATE BETWEEN DATEADD(YEAR, -3, @D) AND DATEADD(YEAR, -2, @D) AND ITEM ='RICE' THEN QTY END) 'RICE PRIOR -3'
, SUM(CASE WHEN DATE BETWEEN DATEADD(YEAR, -2, @D) AND DATEADD(YEAR, -1, @D) AND ITEM ='RICE' THEN QTY END) 'RICE PRIOR -2'
, SUM(CASE WHEN DATE BETWEEN DATEADD(YEAR, -1, @D) AND DATEADD(YEAR, -0, @D) AND ITEM ='RICE' THEN QTY END) 'RICE PRIOR -1'
, SUM(CASE WHEN DATE BETWEEN DATEADD(YEAR, +0, @D) AND DATEADD(YEAR, +1, @D) AND ITEM ='RICE' THEN QTY END) 'RICE POST +1'
, SUM(CASE WHEN DATE BETWEEN DATEADD(YEAR, +1, @D) AND DATEADD(YEAR, +2, @D) AND ITEM ='RICE' THEN QTY END) 'RICE POST +2'
, SUM(CASE WHEN DATE BETWEEN DATEADD(YEAR, +2, @D) AND DATEADD(YEAR, +3, @D) AND ITEM ='RICE' THEN QTY END) 'RICE POST +3'
FROM #TEMP
WHERE DATE >='2002-05-12' AND DATE <'2008-06-12'
GROUP BY ITEM
)
SELECT * FROM CTE;
Upvotes: 1