Reputation: 3093
My data looks like
+-------+-------+-------+------+
| Group | Count | Month | Year |
+-------+-------+-------+------+
| A | 102 | Jan | 2015 |
| B | 20 | Jan | 2016 |
| C | 30 | Feb | 2015 |
| A | 10 | Jan | 2016 |
| C | 20 | Feb | 2016 |
+-------+-------+-------+------+
I want the output like
+-------+-------+------+-------+
| Group | Month | 2015 | 2016 |
+-------+-------+------+-------+
| A | Jan | 102| 10 |
| B | Jan | 20 | 0 |
| C | Feb | 30 | 20 |
+-------+-------+------+-------+
I tried using PIVOT but I'm not sure if it will show the outcome as I want.
The below query is a poor attempt by me (doesn't work)-
SELECT 'Total' AS Total,
[2015], [2016]
FROM
(SELECT DATENAME(YEAR,[mydate]) as Y, Datename(month,[mydate]) as M
FROM incidents) AS SourceTable
PIVOT
(
count(DATENAME(YEAR,[mydate]))
FOR DATENAME(YEAR,[mydate]) IN (2015,2016)
) AS PivotTable;
My date column is in this format 2016-01-20 03:00:11.000
. I use MONTH()
and DATENAME
function to extract month number and name.
Upvotes: 7
Views: 140
Reputation: 17935
There's really no need for the actual pivot
operation.
select
"Group", "Month",
case when "Year" = 2015 then sum("Count") end as "2015",
case when "Year" = 2016 then sum("Count") end as "2016"
from incidents
group by "Group", "Month"
The sum()
aggregate is just a dummy function with this sample data. It could just as easily be min()
or max()
or avg()
even.
Upvotes: 3
Reputation: 9143
I think this is what you need:
WITH Src AS
(
SELECT * FROM (VALUES
('A',102, 'Jan', 2015),
('B', 20, 'Jan', 2016),
('C', 30, 'Feb', 2015),
('A', 10, 'Jan', 2016),
('C', 20, 'Feb', 2016)) T([Group], Count, Month, Year)
)
SELECT [Group],Month,ISNULL([2015],0) [2015],ISNULL([2016],0) [2016] FROM Src
PIVOT
(SUM(Count) FOR Year IN ([2015], [2016])) AS Pvt
ORDER BY [Group],Month
Upvotes: 6