2016-05-23 50 views
2

所以分離組行,我有一個表像行,以便如何通過一個特定的行中SQL

編輯:增加2列
第二個編輯:刪除一個列的原因IM懶惰,不希望將其添加。

Ev_Message  Ev_Comment    EV_Custom1   Ev_Time_Ms  
------------------------------------------------------------------------------------- 
Machine 1 Alarm 5/23/2016 11:02:00 AM Alarms Scanned  25    
Machine 1 Alarm 5/23/2016 11:00:00 AM Alarms Scanned  686 
Machine 1 Alarm 5/23/2016 11:00:00 AM Light curtain  537 
Machine 1 Alarm 5/23/2016 11:00:00 AM Guard door open  346 
Machine 1 Alarm 5/23/2016 11:00:00 AM No control voltage 135 
Machine 1 Alarm 5/23/2016 10:38:34 AM Alarms Scanned  269 
Machine 1 Alarm 5/23/2016 10:38:29 AM Alarms Scanned  378 
Machine 1 Alarm 5/23/2016 10:38:29 AM Guard door open  156 
Machine 1 Alarm 5/23/2016 10:38:25 AM Alarms Scanned  654 
Not an Alarm  5/23/2016 10:38:25 AM Not an Alarm   467  
Machine 1 Alarm 5/23/2016 10:38:25 AM Guard door open  234 
Machine 1 Alarm 5/23/2016 10:38:25 AM No control voltage 67 
Machine 1 Alarm 5/23/2016 10:38:23 AM Alarms Scanned  124 
Machine 1 Alarm 5/23/2016 10:38:23 AM No control voltage 100 

每次掃描報警時,都會添加一個「警報掃描」行。任何警報將添加一個特定的Ev_Custom1行。任何時候警報的狀態發生變化時都會對警報進行掃描。有超過九百個獨特的報警信息。我想我的查詢返回的是這樣的

Alarm Message  Alarm Start Time  Alarm Stop Time 
---------------------------------------------------------------- 
No control voltage 5/23/2016 10:38:23 AM 5/23/2016 10:38:29 AM 
Guard door open  5/23/2016 10:38:25 AM 5/23/2016 10:38:34 AM 
No control voltage 5/23/2016 11:00:00 AM 5/23/2016 11:02:00 AM 
Guard door open  5/23/2016 11:00:00 AM 5/23/2016 11:02:00 AM 
Light curtain  5/23/2016 11:00:00 AM 5/23/2016 11:02:00 AM 

現在,我知道當警報關閉,因爲我得到沒有報警的「報警掃描」的消息在同一時間或下次掃描有其他報警但與以前不一樣。但我不知道如何告訴SQL。這將是在兩個日期之間過濾的查詢。我想我可以通過Group byMin(Ev_Comment) As StartTimeMax(Ev_Comment) As AlmostEndTime選擇一些東西,以便從以下「警報已掃描」行中獲取時間戳EndTime,但是如果我在同一個警報中關閉多次時間框架。我有能力改變進入表格的數據,但有900個警報,我的自由是有限的。

第二個編輯:

WITH T AS (SELECT  s.Ev_Comment AS start_time, MIN(COALESCE (e.Ev_Comment, s.Ev_Comment)) AS end_time 
        FROM   A AS s INNER JOIN 
              A AS e ON s.Ev_Comment < e.Ev_Comment AND s.Ev_Custom1 = 'Alarms Scanned' AND e.Ev_Custom1 = 'Alarms Scanned' 
        GROUP BY s.Ev_Comment) 
SELECT  T_1.start_time, T_1.end_time, A.Ev_Custom1 
FROM   A INNER JOIN 
         T AS T_1 ON A.Ev_Comment LIKE T_1.start_time 
WHERE  (A.Ev_Custom1 <> 'Alarms Scanned') 

這是查詢我目前使用過基於詹姆斯·K·洛登的非常有用的答案。我的查詢設計人員稍微調整了一下語法,我更改了最後的'FROM ... ON ...'語句以過濾掉報警開始時間與前一時間段的結束時間相匹配的行。我仍然有一個問題。如果警報持續時間超過一個週期就像從10時38分25秒到十點38分34秒的「防護門打開」,那麼它會在兩個單獨的行顯示像這樣:

start_time    end_time    EV_Custom1 
--------------------- --------------------- ------------- 
5/23/2016 10:38:29 AM 5/23/2016 10:38:34 AM Guard door open 
5/23/2016 10:38:25 AM 5/23/2016 10:38:29 AM Guard door open 

當理想是什麼我想要的是:

start_time    end_time    EV_Custom1 
--------------------- --------------------- ------------- 
5/23/2016 10:38:25 AM 5/23/2016 10:38:34 AM Guard door open 
+2

谷歌「SQL差距和島嶼問題」,看看你找到的例子有助於你開始。 –

+0

我大概可以添加一個Ev_Custom2列,該列包含一個隨每次掃描都遞增的整數。這將允許我使用類似的東西。謝謝你的提示。 –

+0

這是我正在尋找的完整解決方案。 http://stackoverflow.com/questions/37468189/how-to-group-consecutive-rows –

回答

1

實際上,您提供的數據中沒有足夠的信息來產生您想要的結果。不過,我可以讓你在那裏。

通過將表格連接到它自己可以找到警報週期。

select s.Ev_Comment as start_time 
      , min(coalesce(e.Ev_Comment, s.Ev_Comment)) 
      as end_time 
    from A as s join A as e 
    on s.Ev_Comment < e.Ev_Comment 
    and s.EV_Custom1 = 'Alarms Scanned' 
    and e.EV_Custom1 = 'Alarms Scanned' 
    group by s.Ev_Comment 

    ; 
start_time    end_time    
--------------------- --------------------- 
5/23/2016 10:38:23 AM 5/23/2016 10:38:25 AM 
5/23/2016 10:38:25 AM 5/23/2016 10:38:29 AM 
5/23/2016 10:38:29 AM 5/23/2016 10:38:34 AM 
5/23/2016 10:38:34 AM 5/23/2016 11:00:00 AM 
5/23/2016 11:00:00 AM 5/23/2016 11:02:00 AM 

要找到在這些間隔期間發生的事情,請將該結果加入表中,其中even在開始和結束時間之間。我只是要顯示光幕事件:

with T as (
    select s.Ev_Comment as start_time 
      , min(coalesce(e.Ev_Comment, s.Ev_Comment)) 
      as end_time 
    from A as s join A as e 
    on s.Ev_Comment < e.Ev_Comment 
    and s.EV_Custom1 = 'Alarms Scanned' 
    and e.EV_Custom1 = 'Alarms Scanned' 
    group by s.Ev_Comment 
) 
select start_time, end_time, EV_Custom1 
from A join T 
on Ev_Comment between start_time and end_time 
where EV_Custom1 <> 'Alarms Scanned' 
; 

start_time    end_time    EV_Custom1 
--------------------- --------------------- ------------- 
5/23/2016 10:38:34 AM 5/23/2016 11:00:00 AM Light curtain 
5/23/2016 11:00:00 AM 5/23/2016 11:02:00 AM Light curtain 
... 

下面是該事件本身進行比較。

select * from A where EV_Custom1 = 'Light curtain' 
Ev_Message  Ev_Comment    EV_Custom1 
--------------- --------------------- ------------- 
Machine 1 Alarm 5/23/2016 11:00:00 AM Light curtain 

的問題是,一旦有報警期間,這是不可能的唯一標識該項目所屬的時期,因爲它的時間等於一個週期的結束和另一個開始。

要解決該問題,您需要更精細的時間戳或另一列行號。 (你不能依賴頁面上行顯示的順序,因爲表中的行沒有順序。)我想你可以從那裏得出細節。

+0

我有另一列包含從時間戳毫秒。由於掃描時間較慢,它們都略顯獨特。謝謝你的詳細答案,我會嘗試一下。 –

+0

我將你的解決方案添加到我的問題中。還有一個問題。你能幫我嗎? –

相關問題