I have a stored proc that produces a table like this:
PeriodStart PeriodEnd TotalActive TotalAdded TotalRemoved
2011-03-01 2011-03-07 123 456 789
2011-03-08 2011-03-14 567 789 123
2011-03-15 2011-03-21 444 555 666
etc…
I need to display the results in a table that looks like this:
03-01-2011 03-08-2011 03-15-2011
Active 123 567 444
Added 456 789 555
Removed 789 123 666
I’ve never had to use PIVOT before so I’m a little unsure of how to modify the below SQL in order to achieve the desired result. Here’s the sproc:
ALTER PROCEDURE [dbo].[TrendReport]
@DateStart datetime,
@DateEnd datetime,
@Frequency varchar(5)
AS
BEGIN
SELECT
PeriodStart,
PeriodEnd,
SUM(TotalActive) As TotalActive,
SUM(TotalAdded) As TotalAdded,
SUM(TotalRemoved) As TotalRemoved
FROM (
SELECT
PeriodStart = CASE @Frequency
WHEN 'day' THEN DATEADD(hour, 0, DATEDIFF(DAY, 0, [Date]))
WHEN 'week' THEN DATEADD(hour, 0, DATEDIFF(DAY, 0, DATEADD(DAY, 1 - DATEPART(WEEKDAY, [Date]), [Date])))
WHEN 'month' THEN DATEADD(hour, 0, DATEDIFF(DAY, 0, DATEADD(MONTH, DATEDIFF(MONTH, 0, [Date]), 0)))
WHEN 'quarter' THEN DATEADD(hour, 0, DATEDIFF(DAY, 0, DATEADD(QUARTER, DATEDIFF(QUARTER, 0, [Date]), 0)))
WHEN 'year' THEN DATEADD(hour, 0, DATEDIFF(DAY, 0, DATEADD(YEAR, DATEDIFF(YEAR, 0, [Date]), 0)))
END,
PeriodEnd = CASE @Frequency
WHEN 'day' THEN DATEADD(s, -1, DATEADD(day, 1, DATEDIFF(DAY, 0, [Date])))
WHEN 'week' THEN DATEADD(s, -1, DATEADD(hour, 0, DATEDIFF(DAY, -1, DATEADD(DAY, 7 - DATEPART(WEEKDAY, [Date]), [Date]))))
WHEN 'month' THEN DATEADD(s, -1, DATEADD(hour, 0, DATEDIFF(DAY, -1, DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH, 0, [Date]) + 1, 0)))))
WHEN 'quarter' THEN DATEADD(s, -1, DATEADD(hour, 0, DATEDIFF(DAY, -1, DATEADD(DAY, -1, DATEADD(QUARTER, DATEDIFF(QUARTER, 0, [Date]) + 1, 0)))))
WHEN 'year' THEN DATEADD(s, -1, DATEADD(hour, 0, DATEDIFF(DAY, -1, DATEADD(DAY, -1, DATEADD(YEAR, DATEDIFF(YEAR, 0, [Date]) + 1, 0)))))
END,
TotalActive,
TotalAdded,
TotalRemoved
FROM TrendReport P
WHERE [Date] BETWEEN @DateStart AND @DateEnd
) s
GROUP BY
PeriodStart,
PeriodEnd
ORDER BY PeriodStart
END
You actually need to first apply UNPIVOT to rotate the three quantity types from columns to rows and then apply PIVOT to rotate the period start date to columns and aggregate the quantities.
Here’s the thing with using the PIVOT operator though, you need to know what columns you will have ahead of time (03-01-2011, 03-08-2011, 03-15-2011), it will need hard coded into the query (unless you want to get down and dirty with dynamic sql, which i would read up on before using in production)
Here is the solution: