2012-05-03 20 views
3

我有一個包含索引數據的表,每行都有一個開始和結束時間。查詢此表並獲取其時間跨度處於總體時間段(通常爲從00:00:00到23:59:59的一天)內的索引行列表很簡單。選擇在大範圍內綁定的一組小範圍內發生的所有時間(小時/分鐘) - 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 
... 

我需要的是一個高效查詢(無光標或其他環路),將產生一個結果集給我的每一個行分鐘中的至少一秒落入至少一個指數的時間範圍內:

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秒(因此每分鐘產生幾行,因此希望整合以節省網絡帶寬),但我不能保證;一些行可以跨越較長的時間段,例如02:20:34的start_time和02:23:43的end_time。給定一個這樣的跨度,結果集必須包括2:20,2:21,2:22和2:23,通過UNION查詢start_time和end_time的查詢,你不會得到結果集。

這裏是踢球者:查詢必須與MSDE引擎兼容,MSDE引擎基本上是MSS 2000.所以,沒有CTE(或者我已經這樣做了)。

回答

2

如果通過高效您的意思是最小CPU時間,讀取等,那麼你需要一個查找表。

創建一個包含DATETIMEs全天1440分鐘的表格。

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 

實際上,您正在緩存一些計算。沒有試圖填補數據點之間的差距。


旁白上的日期時間界限

另外請注意,我用的是開始年底值不同。

如果我想覆蓋整個一天,我不會說2012-01-01 00:00:002012-01-01 23:59:59。如果表中包含一個半秒後的值?

DateTimes不是真的離散值值,它們是連續的。因此我使用2012-01-01 00:00:00高達,但不包括,2012-01-02 00:00:00

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

這樣一來,不管是什麼級別的精度x的存儲爲,如果它代表了第一個什麼2012年1月,我抓住了它。

+0

以秒爲單位擊敗我。+1這與使用這裏描述的數字表幾乎相同:http://stackoverflow.com/questions/10819/sql-auxiliary-table-of-numbers – RThomas