按DateTime间隔过滤SQL行

问题描述 投票:0回答:3

我在SQL Server 2016中有一个表,其中包含数百万个日志,我们需要在存储过程中对其进行过滤。每个日志都有一个LogTime字段,我将用于此过滤。我想只返回相隔超过15分钟的日志,跳过那些在LogTime方面彼此太接近的日志。

日志通常在几秒钟之内,因此该时间间隔将适当地限制日志。我也不关心跳过大多数日志项。如果下一个日志距离小时数,则日志之间的间隔大于15分钟也无关紧要,只要间隔时间至少为15分钟。

因此,例如,第一个日志是在15:30,跳过所有日志,直到15:45。在15:46找到下一个日志并继续这样做。

我需要的输出示例:

15:30 - Log Content
15:46 - Log Content
16:12 - Log Content
18:00 - Log Content

我一直在通过反复试验来搜索各种各样的东西。不幸的是,我的SQL知识并没有延伸到很长时间,而且我无法创建一个在任何体面的时间范围内运行的解决方案。

sql sql-server sql-server-2016
3个回答
0
投票

试试这个。

WITH CTE
AS
(
    SELECT
        SeqNo = 1,
        LogTime = MIN(LogTime)
        FROM LogTable

    UNION ALL

    SELECT
        SeqNo = SeqNo+1,
        LogTime = DATEADD(MINUTE,15,LogTime)
        FROM CTE
            WHERE LogTime < GETDATE()
            OR SeqNo < 100
)
SELECT
    *
    FROM LogTable LT
        WHERE EXISTS
        (
            SELECT 1 FROM CTE WHERE LogTime = LT.LogTime
        )

这将显示日志表开头的所有记录,间隔为15分钟。直到100个不同的时间段或时间表当前时间,这是第一次


0
投票

这个评论太长了。

正如您所描述的那样,它的计算成本非常高。您可以使用递归CTE或游标来解决它。这两种方法都需要很长时间。

有两种选择。第一种是将每个日期/时间截断为15分钟,然后拉出第一个。你可以这样做:

select t.*
from (select t.*,
             row_number() over (partition by cast(logtime as date), datepart(hour, logtime), datepart(minute, logtime) / 4
                                order by logtime) as seqnum
      from t
     ) t
where seqnum = 1;

另一种方法是在存在15分钟或更长的间隙时按顺序取第一个。为此,请使用lag()

select t.*
from (select t.*, lag(logtime) over (order by logtime) as prev_logtime
      from t
     ) t
where logtime > dateadd(minute, 15, prev_logtime) or prev_logtime is null;

0
投票

一种简单的方法是使用类似于此的查询,该查询获取每个记录的上一次时间并计算它们之间的分钟数。

SELECT * FROM YourTable 
WHERE DateDiff(mi, (SELECT TOP 1 LogTime FROM YourTable as sub 
  WHERE YourTable.LogTime > sub.LogTime ORDER BY LogTime DESC), LogTime) > 15
© www.soinside.com 2019 - 2024. All rights reserved.