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