SQL Server:选择时间戳值接近子查询中的值的行

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

我有一个日志表,其中包括 id、时间戳、消息,其中

Message
值有时包含“警告”。

SELECT TimeStamp 
FROM Logs 
WHERE Message LIKE '%WARNING%'

我需要的是该组时间两侧 5 分钟以内的行。我知道

BETWEEN
DATEADD
-5 分钟和 +5 分钟可以实现单个值。

如何对一组值执行此操作?我有办法组合 CTE 和 UNION ALL 还是我必须在结果集中移动光标?

更新

我尝试过使用 CTE。

declare @searchTerm varchar(50) = '%WARNING%';
declare @searchDate datetime = '2023-11-01';
declare @id int;
declare @eventTime datetime;
declare @lowRange int = -5;
declare @highRange int = 5;

WITH cteEvents as (
    select Id, EventTime from Veneer.dbo.Logs where EventMessage LIKE @searchTerm and EventTime > @searchDate
)
SELECT * 
    from Logs l
    left outer join cteEvents ev on l.Id=ev.Id 
    where l.EventTime between DATEADD(MINUTE, @lowRange, ev.EventTime) and DATEADD(MINUTE, @highRange, ev.EventTime)

最终结果仅是带有搜索词“WARNING”的记录。该时间段内的周围记录均未出现。我尝试了

INNER
LEFT
RIGHT
连接。我尝试过,每个都是第一个或最后一个。 TIA - 迈克

sql-server union common-table-expression
1个回答
1
投票

试试这个,不需要 CTE。获取所有警告日志,然后使用 BETWEEN 连接到任意一侧警告后 5 分钟内的任何日志。

declare @logs table([sid] int not null identity, [timestamp] datetime, [message] nvarchar(100));

insert into @logs values(DATEADD(MINUTE, 20, CURRENT_TIMESTAMP), N'TEST1');
insert into @logs values(DATEADD(MINUTE, 15, CURRENT_TIMESTAMP), N'TEST2');
insert into @logs values(DATEADD(MINUTE, 10, CURRENT_TIMESTAMP), N'TEST3');
insert into @logs values(DATEADD(MINUTE, 5, CURRENT_TIMESTAMP), N'TEST4');
insert into @logs values(DATEADD(MINUTE, 0, CURRENT_TIMESTAMP), N'WARNING: TEST5');
insert into @logs values(DATEADD(MINUTE, -5, CURRENT_TIMESTAMP), N'TEST6');
insert into @logs values(DATEADD(MINUTE, -10, CURRENT_TIMESTAMP), N'TEST7');
insert into @logs values(DATEADD(MINUTE, -15, CURRENT_TIMESTAMP), N'TEST8');
insert into @logs values(DATEADD(MINUTE, -20, CURRENT_TIMESTAMP), N'TEST9');
insert into @logs values(DATEADD(MINUTE, -25, CURRENT_TIMESTAMP), N'WARNING: TEST10');

WITH CTE AS
(
    select [timestamp]--get distinct dates
    from
        @logs l
    where
        [message] like '%WARNING%'
    group by    
        [timestamp]
)
SELECT l.*
FROM 
    CTE lw
    inner join @logs l on 
        l.[timestamp] between DATEADD(MINUTE, -5, lw.[timestamp]) AND DATEADD(MINUTE, 5, lw.[timestamp])
© www.soinside.com 2019 - 2024. All rights reserved.