1

データベースに数時間データがある場合でも、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月のすべてで表示される必要があります。

いくつか試してみましたが、今のところ運がありませんでした。

4

2 に答える 2

2

一時テーブルまたは CTE を使用する代わりに、永続テーブルを使用します。ほとんどすべてのデータベースで、数値 (または整数) テーブルとカレンダー テーブルがあると非常に便利です。そうすれば、これらのテーブルで外部結合を実行して、「実際の」データには存在しない欠落した数値や日付を埋めるのが簡単になるため、クエリが簡単になります。もちろん、それは他の多くの用途に加えてです.

別の方法は、重複する CTE や保守不可能なハードコードされた関数をコード全体に分散させることです。

于 2012-05-10T13:49:09.737 に答える
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 はパフォーマンスが低下する可能性があります。だから賢く使う

于 2012-05-10T10:56:14.527 に答える