我有一个名为Incidents
的表。我想要一个SQL查询,它返回按月拆分的事件数。开始年份是2010年,但结束年份将是变数。
示例Incidents
表:
DateLogged IncidentRef
----------- ------------
2015-04-05 1
2014-06-04 2
2013-01-01 3
2012-12-10 4
2011-10-15 5
2010-10-01 6
2012-12-11 7
2011-10-10 8
2010-10-10 9
查询返回:
Year Jan Fev Mar Abr Mai Jun Jul Ago Set Out Nov Dez
2010 0 0 0 0 0 0 0 0 0 2 0 0
2011 0 0 0 0 0 0 0 0 0 2 0 0
2012 0 0 0 0 0 0 0 0 0 0 0 2
2013 1 0 0 0 0 0 0 0 0 0 0 0
2014 0 0 0 0 0 1 0 0 0 0 0 0
2015 0 0 0 1 0 0 0 0 0 0 0 0
我该如何进行查询?我从哪里开始?
答案 0 :(得分:5)
一种选择是使用条件聚合:
select year(datelogged),
sum(case when month(datelogged) = 1 then 1 else 0 end) Jan,
sum(case when month(datelogged) = 2 then 1 else 0 end) Feb,
...,
sum(case when month(datelogged) = 12 then 1 else 0 end) Dec
from yourtable
group by year(datelogged)
答案 1 :(得分:3)
使用透视:
;with cte as(select year(date) y, month(date) m, ref from table)
select * from cte
pivot(count(ref) for m in([1],[2],...,[12]))p
答案 2 :(得分:1)
没有透视的另一种方法是使用连接:
with years as
(
SELECT 2010 as y
UNION ALL
SELECT 2011
UNION ALL
SELECT 2012
UNION ALL
SELECT 2013
UNION ALL
SELECT 2014
UNION ALL
SELECT 2015
)
select years.y,
sum(case when month(DateLogged) = 1 then 1 else 0) as jan,
sum(case when month(DateLogged) = 2 then 1 else 0) as feb,
sum(case when month(DateLogged) = 3 then 1 else 0) as mar,
sum(case when month(DateLogged) = 4 then 1 else 0) as apr,
-- ...
sum(case when month(DateLogged) = 12 then 1 else 0) as dec,
from years y
left join incidents i on y.y = year(i.DateLogged)
group by y.DateLogged
如果你想让一年变得“充满活力”,那你就有了这样的CTE
with years as
(
SELECT DISTINCT year(i.DateLogged) FROM incidents
)
但这与sgeddes解决方案具有相同的缺点 - 没有值的年份没有出现。
答案 3 :(得分:1)
使用经典 PIVOT :
数据:
CREATE TABLE #Incidents(
DateLogged DATE NOT NULL PRIMARY KEY
,IncidentRef INTEGER NOT NULL );
INSERT INTO #Incidents(DateLogged,IncidentRef) VALUES
('2015-04-05',1),('2014-06-04',2),('2013-01-01',3),
('2012-12-10',4),('2011-10-15',5),('2010-10-01',6),
('2012-12-11',7),('2011-10-10',8),('2010-10-10',9);
查询:
;WITH cte AS
(
SELECT [year] = YEAR(DateLogged),
[month] = CASE MONTH(DateLogged)
WHEN 1 THEN 'Jan' WHEN 2 THEN 'Fev'
WHEN 3 THEN 'Mar' WHEN 4 THEN 'Abr'
WHEN 5 THEN 'Mai' WHEN 6 THEN 'Jun'
WHEN 7 THEN 'Jul' WHEN 8 THEN 'Ago'
WHEN 9 THEN 'Set' WHEN 10 THEN 'Out'
WHEN 11 THEN 'Nov' WHEN 12 THEN 'Dez'
END,
IncidentRef
FROM #Incidents
)
SELECT [Year],Jan, Fev, Mar, Abr, Mai, Jun, Jul, Ago, [Set], Out, Nov, Dez
FROM cte
PIVOT (
COUNT(IncidentRef)
FOR [month] IN (Jan, Fev, Mar, Abr, Mai, Jun,Jul, Ago, [Set], Out, Nov,Dez)
) AS piv;
的 LiveDemo
强>
使用CHOOSE
添加UNION
cte以确保错失年份的零:
;WITH cte AS
(
SELECT [year] = YEAR(DateLogged),
[month] = CHOOSE(MONTH(DateLogged),'Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'),
IncidentRef
FROM #Incidents
UNION ALL
SELECT [year], NULL, NULL
FROM (VALUES (2010),(2011),(2012),(2013),(2014),(2015)) AS t([year])
)
SELECT [Year],Jan, Fev, Mar, Abr, Mai, Jun, Jul, Ago, [Set], Out, Nov, Dez
FROM cte
PIVOT (
COUNT(IncidentRef)
FOR [month] IN (Jan, Fev, Mar, Abr, Mai, Jun,Jul, Ago, [Set], Out, Nov,Dez)
) AS piv
ORDER BY [Year];
的 LiveDemo2
强>