您好我有一个查询,可以获得每月和每年的事件总数 我想要一个显示列中所有不同年份的结果 您能否建议如何使这个查询动态化?
Expected Result:
Month 2013 2014 2015
January 8 0 12
February 9 6 10
March 12 1 9
April 10 13 27
May 9 22 15
June 27 4 20
July 15 12 22
August 20 2 2
September 22 5 10
October 10 8 12
November 0 7 0
December 0 15 0
查询
select DATENAME(MONTH,DateOpened) as Month,
sum(case when year(DateOpened) = '2015' then 1 else 0 end) as [2015],
sum(case when year(DateOpened) = '2014' then 1 else 0 end) as [2014]
from Incidents
group by DATENAME(MONTH,DateOpened), MONTH(DateOpened)
order by MONTH(DateOpened)
感谢您的帮助!
答案 0 :(得分:2)
您可以使用PIVOT
表运算符,如下所示:
SELECT *
FROM
(
SELECT
DATENAME(MONTH,DateOpened) as Month,
DATENAME(Year,DateOpened) AS Year,
DateOpened
FROM Incidents
) AS t
PIVOT
(
COUNT(DateOpened)
FOR Year IN([2013], [2014], [2015])
) AS p;
如果您不需要编写年份列表并动态执行任何年份,则必须使用动态SQL动态运行查询,如下所示:
DECLARE @cols AS NVARCHAR(MAX);
DECLARE @query AS NVARCHAR(MAX);
SELECT @cols = STUFF((SELECT distinct ',' +
QUOTENAME(DATENAME(Year,DateOpened))
from Incidents AS t
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
, 1, 1, '');
SELECT @query = 'SELECT * , '+ @cols + '
FROM
(
select
DATENAME(MONTH,DateOpened) as Month,
DATENAME(Year,DateOpened) AS Year,
DateOpened
FROM Incidents
) AS t
PIVOT
(
COUNT(DateOpened)
FOR Year IN(' + @cols + ')' +
') p';
execute(@query);
这会给你这样的东西:
| Month | 2014 | 2015 | 2014 | 2015 |
|-----------|------|------|------|------|
| April | 0 | 3 | 0 | 3 |
| August | 1 | 1 | 1 | 1 |
| December | 1 | 0 | 1 | 0 |
| February | 0 | 1 | 0 | 1 |
| July | 1 | 1 | 1 | 1 |
| September | 1 | 0 | 1 | 0 |
请注意:两个查询都不会列出原始表上没有日期的任何月份。如果要列出计数为0的表中未列出的任何月份,则必须修改锚点查询,以便列出所有月份,即使未列出:
SELECT
m.Name as Month,
i.Year,
i.DateOpened
FROM
(
VALUES ('Janurary'), ('February'), ('March'),
('April'), ('May'), ('June'),
('July'), ('August'), ('September'),
('October'), ('November'), ('December')
) AS m(Name)
LEFT JOIN
(
SELECT
DATENAME(MONTH,DateOpened) as Month,
DATENAME(Year,DateOpened) AS Year,
DateOpened
FROM Incidents
) AS i ON i.Month = m.Name
并在动态查询中替换它。
这将为您提供零结果的缺失月份:
| Month | 2014 | 2015 | 2014 | 2015 |
|-----------|------|------|------|------|
| Janurary | 0 | 0 | 0 | 0 | <<
| February | 0 | 1 | 0 | 1 |
| March | 0 | 0 | 0 | 0 | <<
| April | 0 | 3 | 0 | 3 |
| May | 0 | 0 | 0 | 0 | <<
| June | 0 | 0 | 0 | 0 | <<
| July | 1 | 1 | 1 | 1 |
| August | 1 | 1 | 1 | 1 |
| September | 1 | 0 | 1 | 0 |
| October | 0 | 0 | 0 | 0 | <<
| November | 0 | 0 | 0 | 0 | <<
| December | 1 | 0 | 1 | 0 |
答案 1 :(得分:0)
一个像这样的简单创建表..
CREATE TABLE #tmpIncidents
(
IncidentName NVARCHAR(50)
, DateOpened DATETIME
)
INSERT INTO #tmpIncidents (IncidentName,DateOpened) VALUES
('Test1',GETDATE()),
('Test1',DATEADD(YEAR,-1,GETDATE())),
('Test1',DATEADD(YEAR,-2,GETDATE())),
('Test1',DATEADD(YEAR,2,GETDATE())),
('Test1',DATEADD(YEAR,1,GETDATE())),
('Test1',DATEADD(YEAR,3,GETDATE()))
然后是多年的构建查询
DECLARE @columnVar NVARCHAR(4000)
SELECT @columnVar =
(SELECT DISTINCT
'[' + CONVERT(NVARCHAR(150),DATEPART(YEAR,DateOpened)) + '],' AS [text()]
FROM #tmpIncidents
FOR XML PATH('')
)
SET @columnVar = (SELECT LEFT(@columnVar,LEN(@columnVar)-1))
--SELECT @columnVar --so you can see how it looks..
然后执行您的查询。
EXEC ('
SELECT
pv.*
FROM
(
SELECT DATENAME(MONTH,DateOpened) AS [DateName], DATEPART(YEAR,DateOpened) AS [YEAR], IncidentName FROM #tmpIncidents
) src
PIVOT
(
COUNT(IncidentName)
FOR [YEAR] IN (' + @columnVar + ')
) pv;
')