即使数据库中有数据存在数小时,如何使用所有小时的返回值创建一个包含组的select语句?
我有以下查询:
SELECT
DAY(OccurredAt) AS [Day],
DATEPART(HOUR,OccurredAt) AS [Hour],
COUNT(ID) AS [Errors]
FROM
Database..Error WITH (NOLOCK)
WHERE
YEAR(OccurredAt) = 2012
AND MONTH(OccurredAt) = 5
GROUP BY
DAY(OccurredAt), DATEPART(HOUR,OccurredAt)
ORDER BY
DAY(OccurredAt), DATEPART(HOUR,OccurredAt)
它会返回如下数据:
Day Hour Errors
1 1 2
1 4 2
1 6 1
1 7 1
1 9 3
1 10 1
1 11 1
1 14 19
1 15 7
1 16 234
1 17 54
1 18 17
1 19 109
1 20 27
1 22 2
2 6 2
2 7 1
2 8 2
2 9 1
2 10 44
2 11 2
2 15 1
2 16 3
2 18 2
2 19 41
2 20 108
2 21 106
2 22 36
2 23 2
我希望它返回这样的数据:
Day Hour Errors
1 0 0
1 1 2
1 2 0
1 3 0
1 4 2
1 5 0
1 6 1
1 7 1
1 8 0
1 9 3
1 10 1
1 11 1
1 12 0
1 13 0
1 14 19
1 15 7
1 16 234
1 17 54
1 18 17
1 19 109
1 20 27
1 21 0
1 22 2
1 23 0
所以基本上我需要在查询结果中显示零错误的小时数。这些将需要显示整个日期范围,在本例中均为2012年5月。
尝试了一些事情但到目前为止没有任何运气。
答案 0 :(得分:2)
使用永久表,而不是使用临时表或CTE。几乎所有数据库中都有一个数字(或整数)表和一个日历表非常有用。然后像你这样的查询变得容易,因为在这些表上进行外连接以填充“真实”数据中不存在的缺失数字或日期很简单。当然,除了它们的许多其他用途之外,还有它。
另一种方法是通过代码散布重复的CTE和/或不可维护的硬编码函数。
答案 1 :(得分:1)
这是我用于每天选择内容的查询:
WITH Dates AS (
SELECT
[Date] = CONVERT(DATETIME,'01/01/2012')
UNION ALL SELECT
[Date] = DATEADD(DAY, 1, [Date])
FROM
Dates
WHERE
Date < '12/31/2012'
)
SELECT [Date]
FROM Dates
OPTION (MAXRECURSION 400)
您可以按照自己喜欢的方式将日期中的连接扩展到所需的表格。
也许不是100%的回答,但这应该可以帮助你继续前进。
编辑:递归CTE表现不佳。所以明智地使用