我有下表
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
答案 0 :(得分: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的答案更复杂,但这可以通过预先计算范围来处理索引。
答案 1 :(得分:1)
SELECT *
FROM RUN
WHERE ABS(DATEDIFF(s, RUN_DATETIME , '14:25:29.563' ))< 30
答案 2 :(得分: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())
变体要求每行都要独立检查,并且不使用索引或范围搜索。这是对整个表格的完整扫描。
修改强>
另请注意,我使用>=
和<
。这是时间范围的标准做法。
例如val >= 0 AND val < 60
和val >= 60 AND val < 120
可确保val = 60
的值仅在一个时间范围内计算。
答案 3 :(得分:0)
我认为RUN_DateTime列包含日期,我们正在进行的比较只有时间'14:25:29.563'。我同意podiluska的回答。我们需要将'14:25:29.563'转换为日期,从RUN_DateTime列中取出日,月,年。我们可以通过Date_Part函数来完成它。