2

一个进程每 15 分钟运行一次(应该运行一次),并将其添加到 MS SQL 2012 日志记录表中。

2013-02-07 10:07:47.000
2013-02-07 09:52:36.000
2013-02-07 09:37:34.000
2013-02-07 09:22:32.000
2013-02-07 09:07:31.000
2013-02-07 08:52:29.000
2013-02-07 08:37:28.000
2013-02-07 08:13:53.000
2013-02-07 07:58:51.000
2013-02-07 07:43:50.000
2013-02-07 07:28:48.000
2013-02-07 07:13:47.000
2013-02-07 06:58:37.000

我需要一个查询的帮助,该查询将返回相隔 > 16 分钟的连续时间戳。在上述记录中,查询将返回 2013-02-07 08:37:28.000 和 2013-02-07 08:13:53.000

编辑 - 添加对 MS SQL 的引用

4

2 回答 2

3

这个问题的答案很大程度上取决于您使用的 RDBMS。

像这样的东西应该适用于 SQL Server 使用DATEDIFFand ROW_NUMBER

WITH CTE AS (
  SELECT ProcessTime, ROW_NUMBER() OVER (ORDER BY ProcessTime DESC) RN
  FROM Process
  )
SELECT P.ProcessTime, 
  P2.ProcessTime as ProcessTime2, 
  DATEDIFF(mi,  P.ProcessTime, P2.ProcessTime)
FROM CTE P
  JOIN CTE P2 ON P.RN = P2.RN + 1
WHERE DATEDIFF(mi, P.ProcessTime, P2.ProcessTime) > 16

它将日期放在 2 个单独的列中——如果愿意,可以很容易地放在一个列中。

这是小提琴

如果您让我们知道 RDBMS,我们可以在需要时组合一个替代解决方案。

对于 Oracle,使用extract( minute from P2.ProcessTime - P.ProcessTime )vs DATEDIFF- 查询的其余部分应该可以工作 - 这里是Fiddle

对于 MySQL,代码会有所不同,因为 MySQL 不支持CTEsROW_NUMBER. 但这应该让你朝着正确的方向前进。

祝你好运。

于 2013-02-07T16:01:37.947 回答
2

基本思路是在序列中放入下一个时间戳,然后选择差值大于16的行。

以下查询使用相关子查询计算下一个时间戳:

select *
from (select t.*,
             (select MIN(t.timestamp) from t t2 where t2.timestamp > t.timestamp
             ) as nextTimestamp
      from t
     ) t
where DATEDIFF(min, timestamp, nextTimestamp) > 16

where子句依赖于数据库,但它提供了如何执行此操作的想法。

在 SQL Server 2012 上,您将执行以下操作:

select *
from (select t.*,
             lead (t.timestamp) over (order by timestamp) as nextTimestamp
      from t
     ) t
where DATEDIFF(mi, timestamp, nextTimestamp) > 16

(假设您的时间戳存储为datetime)。

于 2013-02-07T16:03:26.527 回答