考虑一个包含3列的表格:
Timestamp
:格式hh:mm:ss
,每秒记录在表中PSI
:每秒记录在表中的传感器值Temp
:每秒在表中记录的温度值我想编写一个查询,该查询何时会生成警报
PSI
大于60并且Temp
大于255连续超过60秒或更长时间例如如果PSI > 60 and Temp > 255
的值从01:01:15到01:02:17,则应生成警报。
我尝试使用游标来完成这项工作,但是查询无法正常工作。有人可以帮助解决现有查询吗?另外,有人可以建议对此问题陈述进行替代且简单的查询吗?
我尝试过的查询:
declare @Timestamp time, @PSI int, @Temp int, @final_timestmp time, @status int
set @final_timestmp='01:00:00'
declare cr_alert cursor for
select Timestamp, PSI, Temp
from [dbo].[Sensor_Values]
where PSI > 60 and Temp > 255
order by Timestamp
open cr_alert;
Fetch next from cr_alert into @Timestamp, @PSI, @Temp
while @@FETCH_STATUS = 0
begin
set @status = 0
print @status
if (@Timestamp <> @final_timestmp)
begin
set @status = datediff(second, @final_timestmp, @Timestamp)
if (@status = 1)
begin
set @final_timestmp = @Timestamp;
insert into final_Sensor_Values
select @final_timestmp, @PSI, @Temp
fetch next from cr_alert into @Timestamp, @PSI, @Temp
end
end
end
close cr_alert;
deallocate cr_alert;
样本数据集:
Timestamp PSI Temp
01:01:01 59 264
01:01:02 63 247
01:01:03 56 245
01:01:04 64 262
01:01:05 50 245
01:01:06 57 244
01:01:07 64 251
01:01:08 60 259
01:01:09 52 244
01:01:10 52 242
01:01:11 63 259
01:01:12 56 241
01:01:13 51 252
01:01:14 52 261
01:01:15 50 265
01:01:16 54 251
01:01:17 59 243
01:01:18 64 240
01:01:19 55 265
或者您可以在以下网址中查看数据集。
答案 0 :(得分:0)
declare @t table
(
Timestamp time,
PSI smallint,
Temp smallint,
index clidx clustered(Timestamp)
--id int identity,
--primary key clustered(Timestamp, id)
);
insert into @t(Timestamp, PSI, Temp)
values
('01:01:01', 59, 264),
('01:01:02', 63, 247),
('01:01:03', 56, 245),
('01:01:04', 64, 262),
('01:01:05', 50, 245),
('01:01:06', 57, 244),
('01:01:07', 64, 251),
('01:01:08', 60, 259),
('01:01:09', 52, 244),
('01:01:10', 52, 242),
('01:01:11', 63, 259),
('01:01:12', 56, 241),
('01:01:13', 51, 252),
('01:01:14', 52, 261),
('01:01:15', 50, 265),
('01:01:16', 54, 251),
('01:01:17', 59, 243),
('01:01:18', 64, 240),
('01:01:19', 55, 265);
select *, case when l.totalrows = 5 and l.minPSI > 50 and l.minTemp > 240 then 1 else 0 end as AlertYN
from @t as t
cross apply
(
select min(p.PSI) as minPSI, max(p.PSI) as maxPSI, min(p.Temp) as minTemp, max(p.Temp) as maxTemp, count(*) as totalrows
from @t as p
where p.TimeStamp > dateadd(second, -5, t.TimeStamp) --check for last 5 secs
and p.TimeStamp <= t.TimeStamp
) as l
--where l.minPSI > 50 and l.minTemp > 240
答案 1 :(得分:0)
假设每秒有一行,则可以使用窗口函数:
select sv.*,
(case when min(temp) over (order by timestamp rows between 59 preceding and current row) > 255 and
min(PSI) over (order by timestamp rows between 59 preceding and current row) > 60
then 'Alert!!!'
end) as alert
from [dbo].[Sensor_Values] sv;
如果可能缺少几秒钟,则可以使用:
with sv as (
select sv.*, row_number() over (order by timestamp) as seqnum
from [dbo].[Sensor_Values] sv
)
select sv.*,
(case when min(temp) over (order by seqnum range between 59 preceding and current row) > 255 and
min(PSI) over (order by seqnum range between 59 preceding and current row) > 60
then 'Alert!!!'
end) as alert
from [dbo].[Sensor_Values] sv;
这里唯一的警告是,这可能会在数据开始时生成不必要的警报。