2012-05-03 9 views
3

インデックスデータを含むテーブルがあり、各行に開始時刻と終了時刻があります。このテーブルを照会してタイムラインが重要な期間(通常は00:00:00から23:59:59までの1日)のインデックス行のリストを取得するのは簡単です。大範囲で束縛された一連の小範囲内で発生するすべての時間(時/分)を選択する - SQL 2000

declare @date datetime, @start datetime, @end datetime 

set @date = GetDate() //in production code this is a n input to a stored proc 

//the date component of the current date/time, starting at midnight 
set @start = DateAdd(dd, DateDiff(dd, 0, @date), 0) 

//one second before midnight the next day 
set @end = DateAdd(dd, 1, DateAdd(ss, -1, @start)) 

select idx, start_time, end_time 
from index_data 
where start_time <= @end 
and end_time >= @start 
order by start_time 

結果はこのようなものになるだろう:私は必要なもの

idx   start_time     end_time 
--------------------------------------------------------------- 
495640  2012-05-03 00:17:13.000  2012-05-03 00:17:45.000 
495641  2012-05-03 00:18:20.000  2012-05-03 00:18:51.000 
495642  2012-05-03 00:18:55.000  2012-05-03 00:19:31.000 
495643  2012-05-03 00:34:08.000  2012-05-03 00:34:28.000 
495644  2012-05-03 00:36:21.000  2012-05-03 00:36:41.000 
495646  2012-05-03 01:22:21.000  2012-05-03 01:22:38.000 
495647  2012-05-03 01:24:38.000  2012-05-03 01:24:55.000 
495648  2012-05-03 01:30:11.000  2012-05-03 01:30:29.000 
495649  2012-05-03 01:31:23.000  2012-05-03 01:31:39.000 
495650  2012-05-03 02:09:57.000  2012-05-03 02:10:59.000 
495651  2012-05-03 02:11:00.000  2012-05-03 02:11:00.000 
495652  2012-05-03 02:14:25.000  2012-05-03 02:14:42.000 
495653  2012-05-03 02:31:09.000  2012-05-03 02:31:25.000 
495655  2012-05-03 03:02:32.000  2012-05-03 03:02:51.000 
... 

はそれぞれに私に行を与えて結果セットを生成します効率的クエリ(なしカーソルまたは他のループ)であります少なくとも1つのインデックスの時間範囲内に少なくとも1つのインデックスの時間範囲内に入る、与えられた日の時および分である:

hour min 
---------- 
0  17 
0  18 
0  19 
0  34 
0  36 
1  22 
1  24 
1  30 
1  31 
2  9 
2  10 
2  11 
2  14 
2  31 
3  02 
... 

各インデックスのスターt_timeとend_timeの間隔は通常60秒未満です(したがって、1分あたり数行が生成されるため、ネットワーク帯域幅を節約するための統合が望まれます)。いくつかの行は、例えば、02:20:34のstart_timeと02:23:43のend_timeのような、より長い期間に及ぶことがあります。このようなスパンが与えられた場合、結果セットには2:20、2:21、2:22、および2:23が含まれている必要があります。これは、end_timeのクエリでstart_timeのクエリをUNIONすることでは得られません。

キッカーはです。クエリは基本的にはMSS 2000のMSDEエンジンと互換性がなければなりません。したがって、CTEはです(これはすでに実行済みです)。

答えて

2

効率がの場合は、最小CPU時間、読み取りなどを意味します。ルックアップテーブルが必要です。

日付の1440分をすべてDATETIMEとして含むテーブルを作成します。

DECLARE 
    @date DATETIME, 
    @start DATETIME, 
    @end DATETIME 
SELECT 
    @date = GetDate(), 
    @start = DateAdd(dd, DateDiff(dd, 0, @date), 0), 
    @end = DateAdd(dd, 1, @start) 

SELECT 
    minute_lookup.timestamp, 
    COUNT(*)     AS total_records 
FROM 
    index_data 
INNER JOIN 
    minute_lookup 
    ON minute_lookup.timestamp >= index_data.start_time - @date 
    AND minute_lookup.timestamp < index_data.end_time - @date 
WHERE 
     index_data.start_time < @end 
    AND index_data.end_time > @start 
GROUP BY 
    minute_lookup.timestamp 
ORDER BY 
    minute_lookup.timestamp 

効果的には、計算の一部をキャッシュしています。データポイント間のギャップを埋めることはありません。 DateTimeの境界の上に置き


Anがまた

、私は開始と値は異なるエンドを使用することに注意してください。

私が一日の全体をカバーしたい場合、私は2012-01-01 00:00:002012-01-01 23:59:59とは言いません。その後にテーブルの値が0.5秒含まれる場合はどうなりますか?

DateTimesは実際にはという個別値の値ではなく、連続しています。それは2012年1月1日に何を表している場合はそのように私は、関係なく精度xのどのレベルとして保存されていない、このように2012-01-01 00:00:00件まで、しかし除く、2012-01-02 00:00:00

  • x >= '2012-01-01' AND x < '2012-01-02'

からの利用、Iそれを捕えました。

+0

ほんの数秒で私にそれを打つ。+1ここに記載されているように数字表を使用するのとほぼ同じです:http://stackoverflow.com/questions/10819/sql-auxiliary-table-of-numbers – RThomas

関連する問題