选择由大范围限制的一组小范围内发生的所有时间(小时/分钟)-SQL 2000
我有一个包含索引数据的表,每一行都有一个开始和结束时间。查询此表并获取其时间跨度在一个总体时间段内(通常是从00:00:00到23:59:59的一天)的索引行列表非常简单 我需要的是一个高效的查询(无光标或其他循环),该查询将生成一个结果集,该结果集为给定日期的每小时和每分钟提供一行,其中至少有一秒的时间在至少一个索引的时间范围内:选择由大范围限制的一组小范围内发生的所有时间(小时/分钟)-SQL 2000,sql,datetime,sql-server-2000,Sql,Datetime,Sql Server 2000,我有一个包含索引数据的表,每一行都有一个开始和结束时间。查询此表并获取其时间跨度在一个总体时间段内(通常是从00:00:00到23:59:59的一天)的索引行列表非常简单 我需要的是一个高效的查询(无光标或其他循环),该查询将生成一个结果集,该结果集为给定日期的每小时和每分钟提供一行,其中至少有一秒的时间在至少一个索引的时间范围内: hour min ---------- 0 17 0 18 0 19 0 34 0 36 1 22
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
...
每个索引的开始时间和结束时间通常相隔不到60秒(因此每分钟产生几行,因此需要整合以节省网络带宽),但我不能保证这一点;有些行可以跨越更长的时间段,例如开始时间为02:20:34,结束时间为02:23:43。给定这样的跨度,结果集必须包括2:20、2:21、2:22和2:23,这是将开始时间的查询与结束时间的查询合并时无法得到的
关键是:查询必须与MSDE引擎兼容,该引擎基本上是MSS 2000。因此,没有CTE(或者我已经这样做了)。如果所说的高效是指最短的CPU时间、读取等,那么您需要一个查找表
创建一个包含一天中所有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
声明
@日期时间,
@开始日期时间,
@结束日期时间
挑选
@日期=GetDate(),
@start=DateAdd(dd,DateDiff(dd,0,@date),0),
@end=DateAdd(dd,1,@start)
挑选
分钟。时间戳,
将(*)计为总记录
从…起
索引数据
内连接
分钟查找
分钟时\u lookup.timestamp>=index\u data.start\u time-@date
和minute_lookup.timestamp@start
分组
分钟时间戳
订购人
分钟时间戳
实际上,您正在缓存一些计算。不要试图填补数据点之间的空白
日期时间界限的旁白 另外,请注意,我使用的起始值和结束值不同 如果我想涵盖一整天,我不会说
2012-01-01 00:00:00
到2012-01-01 23:59:59
。如果表中包含半秒后的值,该怎么办
日期时间不是真正的离散值,而是连续的。因此,我使用从2012-01-01 00:00:00
到,但不包括,2012-01-02 00:00:00
x>='2012-01-01'和x<'2012-01-02'
通过这种方式,无论x的存储精度是多少,如果它在2012年1月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
...
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