2

我有下表

2012-05-24 19:00:00.000
2012-07-27 15:51:18.750
2012-07-30 09:40:25.333
2012-07-30 14:25:27.563
2012-07-27 15:51:18.750
2012-07-30 09:40:25.333
2012-07-30 14:25:27.563
2012-05-12 09:23:16.850
2012-05-12 18:00:00.000

我正在尝试进行范围选择,例如

SELECT * FROM RUN WHERE RUN_DATETIME = '14:25:29.563' 

这是一个非常简单的选择,但我的问题是我正在搜索代码的日期与上表中的日期相差 30 秒,所以我需要能够执行与上面相同的操作,但窗口为 30 秒我不确定最好的方法是什么。

此选择不基于另一行,仅基于窗口内的 RUN_DATE 行。

我正在使用 SQL Server 2008 R2

4

4 回答 4

3
SELECT * FROM RUN
WHERE RUN_DATETIME < DATEDADD(s, '14:25:29.563', 30) AND
      RUN_DATETIME > DATEDADD(s, '14:25:29.563', -30)

看起来比 podiluska 的答案更复杂,但这可以通过预先计算范围来处理索引。

于 2012-08-03T09:28:33.743 回答
1
SELECT * 
FROM RUN 
WHERE ABS(DATEDIFF(s, RUN_DATETIME , '14:25:29.563' ))< 30
于 2012-08-03T09:25:09.557 回答
1
SELECT
  *
FROM
  RUN
WHERE
      RUN_DATETIME >= DATEADD(second, -30, '14:25:29.563')
  AND RUN_DATETIME <  DATEADD(second,  30, '14:25:29.563')

这比ABS(DATEDIFF())版本长。但是,它在应用于索引字段时要快得多。

那是因为优化器可以很容易地看到您想要一个连续块中的所有记录。它可以搜索开始,然后搜索结束,并返回其间的所有内容。

ABS(DATEDIFF())变体要求独立检查每一行,并且不使用索引或范围搜索。这是对整个表的完整扫描。


编辑:

另请注意,我使用>=and <。这是时间范围的标准做法。

例如val >= 0 AND val < 60,并val >= 60 AND val < 120确保val = 60仅在一个时间范围内计算 at 的值。

于 2012-08-03T09:28:36.457 回答
0

我认为 RUN_DateTime 列包含日期,我们正在做的比较只是时间在这里'14:25:29.563'。我同意 podiluska 的回答。只是我们需要通过从 RUN_DateTime 列中取出日、月、年将 '14:25:29.563' 转换为日期。我们可以通过 Date_Part 函数来完成。

于 2012-08-03T09:52:38.887 回答