按DateTime间隔过滤SQL行

时间:2017-12-18 13:38:18

标签: sql sql-server sql-server-2016

我在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知识并没有延伸到很长时间,而且我无法创建一个在任何不错的时间范围内运行的解决方案。

3 个答案:

答案 0 :(得分: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个不同的时间段或时间表当前时间,这是第一次

答案 1 :(得分:0)

评论太长了。

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

有两种选择。第一种是将每个日期/时间截断为15分钟,然后拉出第一个。您可以使用以下方式执行此操作:

static void testFunction(VariablesThatCouldBeUsedInFunctions *StructPointer){
        if(bTestElectricFunctions){
        gtk_widget_set_name(GTK_WIDGET(StructPointer->testBtn), "testBtnSuccess");
    //Gtk-CRITICAL **: gtk_widget_set_name: assertion 'GTK_IS_WIDGET (widget)' failed
    }
else{
    printf("untrue\n");
    }
}

另一种方法是在有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;

lag()

答案 2 :(得分: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