2012-05-10 174 views
1

即使在數據庫中有數據存在幾個小時的情況下,如何通過返回所有小時的值來創建具有組的SELECT語句?使用GROUP BY創建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月。

嘗試了幾件事情,但迄今爲止沒有任何運氣。

+3

你需要一個24小時的表格,然後你可以['OUTER JOIN'](http://msdn.microsoft.com/en-us/library/aa213228%28v=sql.80%29.aspx)它。 –

回答

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可以表現不佳。所以明智地使用

2

而不是使用臨時表或CTE,使用永久表。在幾乎所有的數據庫中都有一個數字(或整數)表和一個日曆表是非常有用的。然後像你這樣的查詢就變得容易了,因爲在這些表上進行外部連接很容易,以填補「真實」數據中不存在的缺失數字或日期。當然,除了他們的許多其他用途之外。

另一種方法是通過代碼分散重複的CTE和/或不可維護的硬編碼函數。