选择由大范围限制的一组小范围内发生的所有时间(小时/分钟)-SQL 2000

选择由大范围限制的一组小范围内发生的所有时间(小时/分钟)-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

我有一个包含索引数据的表,每一行都有一个开始和结束时间。查询此表并获取其时间跨度在一个总体时间段内(通常是从00:00:00到23:59:59的一天)的索引行列表非常简单

我需要的是一个高效的查询(无光标或其他循环),该查询将生成一个结果集,该结果集为给定日期的每小时和每分钟提供一行,其中至少有一秒的时间在至少一个索引的时间范围内:

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