2016-11-30 4 views
2

は、私のような私のソーステーブルを持っていたSQL Serverクエリは、最近私が要件に出くわした出現箇所

テーブルには、上記
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に達した)。

予想される第2の結果セットは、少なくとも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 

ご提案/クエリサンプルをお待ちしております。

よろしく、ROW_NUMBERとCTEと再帰CTE

を使用して RON

+0

? MSSQL 2012+でラグ関数とリード関数を使用できる場合は、CTEを使用できます。編集:あなたはあなたの前の質問からだと仮定します.. – Matt

+0

あなたは、セットベースの解決策を介してレコードによって記録されるソリューションを選択しました。 –

+0

こんにちはモートブ、申し訳ありませんが、私は最初に試したものをコンテンツに含めませんでした。私の悪い。私はCTEメソッドを試しましたが、アンカーレコードが間違って設定されているため、正確な結果に到達できませんでした。しかし、後のLukStormは、私が探していた正確な解決策を投稿しました。質問のスニペットを含めるようにします。ありがとうございました。 –

答えて

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 
+0

こんにちはMarkovitz、あなたの解決策をCTEソリューションとして利用することは、大きなソースに適用すると結果を生み出すのに時間がかかることになります。ありがとう。 –

+0

@RonyVarghes - 良い動きのように聞こえます...両方のソリューションの実行時間を分かち合えますか? –

1

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]; 

戻り値:どのようなDBMS

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 
関連する問題