Вы можете использовать аргумент OFFSET
, равный LAG
, чтобы проверить 4 строки назад, чтобы сделать ее 5-строчным окном (считая текущий). Например: lag(Column,Offset,Default)
где столбец - это столбец, смещение - это количество строк назад, а значение по умолчанию - это то, что возвращается в случае сбоя условия (NULL
по умолчанию).
;with cte as(
select
*
,LogicCheck = abs(datediff(hour,[DateTime],lag([DateTime],4) over (partition by SensorID order by [DateTime])))
from #Input
)
select *
from #Input
where SensorID in (select SensorID from cte where LogicCheck = 4)
Это работает с вашими примерами данных, но если есть большие окна, вы должны учитывать это. См. Этот дополнительный пример данных и метод для ухода за большими окнами.
use tempdb
go
Create Table #Input
(
SensorID int
, LocID int
, DateTime datetime
, Voltage float
)
Insert Into #Input
Select 100,200,'1/23/2019 13:00',6 Union All
Select 100,200,'1/23/2019 12:00',8 Union All
select 100,200,'1/23/2019 11:00',6 Union All
Select 100,200,'1/23/2019 10:00',7 Union All
Select 100,200,'1/23/2019 9:00',8 Union All
Select 101,201,'1/23/2019 10:00',8 Union All
Select 101,201,'1/23/2019 9:00',1 Union All
Select 101,201,'1/23/2019 8:00',2 Union All
Select 101,201,'1/23/2019 6:00',8 Union All
Select 101,201,'1/23/2019 5:00',1 Union All
Select 103,203,'1/23/2019 11:00',10 Union All
Select 103,203,'1/23/2019 10:00',11 Union All
Select 103,203,'1/23/2019 9:00',8 Union All
Select 103,203,'1/23/2019 8:00',9 Union All
Select 103,203,'1/23/2019 7:00',9 Union All
Select 103,203,'1/23/2019 6:00',9 Union all --added this row which should be included
Select 103,203,'1/23/2019 4:00',9 --added this row which is a break in the time and shouldn't be returned
;with cte as(
select
*
,Seq = row_number() over (partition by SensorID order by [DateTime])
,LogicCheck = abs(datediff(hour,[DateTime],lag([DateTime],4) over (partition by SensorID order by [DateTime])))
from #Input
)
select
c.SensorID
,c.LocID
,c.DateTime
,c.Voltage
--,c.Seq
--,c.LogicCheck
from
cte c
where exists
(
select SensorID
from cte
where LogicCheck = 4
and cte.SensorID = c.SensorID
and c.Seq <= cte.Seq
and c.Seq >= cte.Seq - 4
)
drop table #Input