2012-05-10 7 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 

だから、基本的にはIクエリー結果にもエラーがない時間が必要です。これらはすべての期間(この場合は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%答えではありませんが、これはあなたが邪魔になるのを助けるはずです。

EDIT:再帰的CTEのパフォーマンスが悪い可能性があります。賢明に使用してください。

2

一時テーブルまたはCTEを使用する代わりに、永久テーブルを使用してください。ほぼすべてのデータベースで、数値(または整数)テーブルとカレンダーテーブルを持つことは非常に便利です。あなたのようなクエリは簡単になります。なぜなら、それらのテーブルに対して外部結合を実行して、実際のデータにはない欠落した数字や日付を記入するのが簡単だからです。それはもちろん、他の多くの用途に加えてあります。

代わりに、コードを使用して重複したCTEや維持不能なハードコードされた機能を散在させることもできます。