最近我遇到了一个要求,我有源表,
Machine_Name| Time | Alarm
------------|---------------------|---------
Mac1 | 2016-11-22 05:15 | 0
Mac1 | 2016-11-22 05:30 | 1
Mac1 | 2016-11-22 05:45 | 1
Mac1 | 2016-11-22 06:00 | 0
Mac1 | 2016-11-22 06:15 | 1
Mac1 | 2016-11-22 06:30 | 1
Mac1 | 2016-11-22 06:45 | 1
Mac1 | 2016-11-22 07:00 | 1
Mac1 | 2016-11-22 07:15 | 1
Mac1 | 2016-11-22 07:30 | 1
Mac2 | 2016-11-22 05:15 | 0
Mac2 | 2016-11-22 05:30 | 0
Mac2 | 2016-11-22 05:45 | 1
Mac2 | 2016-11-22 06:00 | 1
Mac2 | 2016-11-22 06:15 | 1
Mac2 | 2016-11-22 06:30 | 1
Mac2 | 2016-11-22 06:45 | 0
Mac2 | 2016-11-22 07:00 | 1
上表列出了设施中安装的差异化机器的详细信息及其发布警报'每个时期的状态(每15分钟一次)。
现在我需要计算此警报的相关性。对于任何单个警报,相关性为25%。如果机器连续4个时间(1小时)发出警报,则将最大相关性归档100%。
如果警报连续超过4个(1小时),则相关性保持不变100%。
上述源表的预期结果集如下,
Machine_Name| Time | Alarm | Alert_Relevancy(%)
------------|---------------------|---------|---------------
Mac1 | 2016-11-22 05:15 | 0 | 0
Mac1 | 2016-11-22 05:30 | 1 | 25
Mac1 | 2016-11-22 05:45 | 1 | 50
Mac1 | 2016-11-22 06:00 | 0 | 0
Mac1 | 2016-11-22 06:15 | 1 | 25
Mac1 | 2016-11-22 06:30 | 1 | 50
Mac1 | 2016-11-22 06:45 | 1 | 75
Mac1 | 2016-11-22 07:00 | 1 | 100
Mac1 | 2016-11-22 07:15 | 1 | 100
Mac1 | 2016-11-22 07:30 | 1 | 100
Mac2 | 2016-11-22 05:15 | 0 | 0
Mac2 | 2016-11-22 05:30 | 0 | 0
Mac2 | 2016-11-22 05:45 | 1 | 25
Mac2 | 2016-11-22 06:00 | 1 | 50
Mac2 | 2016-11-22 06:15 | 1 | 75
Mac2 | 2016-11-22 06:30 | 1 | 100
Mac2 | 2016-11-22 06:45 | 0 | 0
Mac2 | 2016-11-22 07:00 | 1 | 25
如果我还可以获得一个查询来选择那些连续引发至少4次的警报系列(相关性达到100),那将会很棒。
预期的第二个结果集如下,我已经删除了连续至少4次不是1的任何警报系列。
Machine_Name| Time | Alarm | Alert_Relevancy(%)
------------|---------------------|---------|---------------
Mac1 | 2016-11-22 06:15 | 1 | 25
Mac1 | 2016-11-22 06:30 | 1 | 50
Mac1 | 2016-11-22 06:45 | 1 | 75
Mac1 | 2016-11-22 07:00 | 1 | 100
Mac1 | 2016-11-22 07:15 | 1 | 100
Mac1 | 2016-11-22 07:30 | 1 | 100
Mac2 | 2016-11-22 05:45 | 1 | 25
Mac2 | 2016-11-22 06:00 | 1 | 50
Mac2 | 2016-11-22 06:15 | 1 | 75
Mac2 | 2016-11-22 06:30 | 1 | 100
提前感谢您的建议/查询示例。
此致 RON
答案 0 :(得分:2)
select Machine_Name
,time
,Alarm
,case when alarm_seq >= 4 then 4 else alarm_seq end * 25
from (select *
,sum (Alarm) over
(
partition by Machine_Name,group_id
order by time
) as alarm_seq
from (select *
,count (nullif(alarm,1)) over
(
partition by Machine_Name
order by time
) as group_id
from t
) t
) t
select Machine_Name
,time
,Alarm
,case when alarm_seq >= 4 then 4 else alarm_seq end * 25
from (select *
,sum (Alarm) over
(
partition by Machine_Name,group_id
order by time
) as alarm_seq
,sum (Alarm) over
(
partition by Machine_Name,group_id
) as alarms
from (select *
,count (nullif(alarm,1)) over
(
partition by Machine_Name
order by time
) as group_id
from t
) t
) t
where alarms >= 4
and alarm = 1
答案 1 :(得分:1)
使用带有row_number和递归CTE的CTE
SQL使用表变量进行演示。
declare @SourceTable table (Machine_Name varchar(4), [Time] datetime, Alarm bit);
insert into @SourceTable values
('Mac1','2016-11-22 05:15',0),
('Mac1','2016-11-22 05:30',1),
('Mac1','2016-11-22 05:45',1),
('Mac1','2016-11-22 06:00',0),
('Mac1','2016-11-22 06:15',1),
('Mac1','2016-11-22 06:30',1),
('Mac1','2016-11-22 06:45',1),
('Mac1','2016-11-22 07:00',1),
('Mac1','2016-11-22 07:15',1),
('Mac1','2016-11-22 07:30',1),
('Mac2','2016-11-22 05:15',0),
('Mac2','2016-11-22 05:30',0),
('Mac2','2016-11-22 05:45',1),
('Mac2','2016-11-22 06:00',1),
('Mac2','2016-11-22 06:15',1),
('Mac2','2016-11-22 06:30',1),
('Mac2','2016-11-22 06:45',0),
('Mac2','2016-11-22 07:00',1);
;with CTE as
(
select
row_number() over (partition by Machine_Name order by [Time]) as rn,
Machine_Name, [Time], Alarm
from @SourceTable
),
RECURSIVE_CTE as
(
select Machine_Name, [Time], Alarm, rn, rn as rn_root, 0 as Relevancy
from CTE
where Alarm = 0
UNION ALL
select CTE.Machine_Name, CTE.[Time], CTE.Alarm, CTE.rn, R.rn_root, case when R.Relevancy = 100 then 100 else (R.Relevancy + 25) end
from RECURSIVE_CTE R
JOIN CTE ON (R.Machine_Name = CTE.Machine_Name AND R.rn + 1 = CTE.rn AND CTE.Alarm = 1)
)
select R.Machine_Name, R.[Time], R.Alarm, R.Relevancy as [Alert_Relevancy(%)]
from RECURSIVE_CTE R
INNER JOIN (select Machine_Name, rn_root from RECURSIVE_CTE where Relevancy = 100 group by Machine_Name, rn_root) M
ON (R.Machine_Name = M.Machine_Name and R.rn_root = M.rn_root)
where R.Relevancy > 0
order by R.Machine_Name, R.[Time];
返回:
Mac1 2016-11-22 06:15:00.000 1 25
Mac1 2016-11-22 06:30:00.000 1 50
Mac1 2016-11-22 06:45:00.000 1 75
Mac1 2016-11-22 07:00:00.000 1 100
Mac1 2016-11-22 07:15:00.000 1 100
Mac1 2016-11-22 07:30:00.000 1 100
Mac2 2016-11-22 05:45:00.000 1 25
Mac2 2016-11-22 06:00:00.000 1 50
Mac2 2016-11-22 06:15:00.000 1 75
Mac2 2016-11-22 06:30:00.000 1 100