查询0-30分钟组中的数据

时间:2014-10-28 17:45:34

标签: sql sql-server sql-server-2008-r2 datediff dateadd

我有一个脚本,每30分钟运行一次查询,查找前30分钟内的新记录。为了解释脚本运行的任何类型的延迟,我想查看上一个0:00-30:00分钟和30:01-59:59分块。

例如,如果我的脚本在上午11:00运行,我希望它能找到具有

的新行。

entered_date > 10:30 am AND < 11:00 am

当它在上午11:30运行时,我期待来自`entered_date&gt;的新行。上午11:00和&lt;上午11:30。

做这样的事情只能让最后一次跑30分钟:

SELECT
    fa.entered_date,
    fa.text
FROM
    form_answers fa 
WHERE
    AND fa.value = 1
    AND fa.entered_date >= DATEADD(mi, -30, GETDATE())

因此,如果我的脚本以某种方式延迟了几秒钟,并在11:00:02运行,我可能会错过一张entered_date为10:30:01的记录。

编辑:

最终为我工作的是:

    fa.entered_date BETWEEN 
        DATEADD(mi,-30,CONVERT(VARCHAR(19),DATEADD(mi, DATEDIFF(mi, 0, GETDATE())/30*30, 0))) 
    AND 
        DATEADD(mi, DATEDIFF(mi, 0, GETDATE())/30*30, 0)

2 个答案:

答案 0 :(得分:3)

评论太长了。

根据脚本中的时钟时间是一个坏主意。您的脚本可能由于其他原因而无法运行 - 例如,SQL Server代理程序未运行,或者服务器在运行时重新启动,或者新用户意外取消选中框。或者,它可能会在某段时间内运行两次。

如果需要健壮性,请保留上次运行脚本的日志表。然后从日志中读取,如:

select @lastlogtime = max(lastreadtime)
from log;

在查询中使用它而不是依赖于时钟。

答案 1 :(得分:0)

没有可靠的方法来处理&#34; new&#34;基于时间的记录 - 即使你追踪&#34; last&#34;处理时间,可能会有错过的记录,或者两次处理的记录。

一些替代方法:

  • 跟踪已处理的最后一个entered_date并处理在此之后添加的任何内容。
  • 跟踪处理的最后一个ID,并处理具有更高ID的任何记录(假设您的表使用递增键)。
  • 在您的记录中添加标记或状态字段,以了解它们是否已被处理
  • 使用添加记录时填充的队列(使用触发器)并定期处理。

如果你 DO 必须单独依靠时钟,那么我会绕过&#34;当前&#34;时间到最近的30分钟间隔,并从那里锁定30分钟。因此,如果当前时间为11:00:02,则会将其四舍五入为11:00:00,并处理在10:30:0011:00:00之间添加的记录。