2017-07-25 87 views
-2

below is the sample data需要SQL查詢來獲取時間差基於狀態

我需要的總時間時EbstatusdgstatusON,直到下次DgStatusOFF

例如,如果我們考慮以下數據:

Ebstatus | dgstatus | ReadTime 
    ON | ON | 16/07/2017 3:00:00 
    ON | ON | 16/07/2017 4:00:00 
    ON | OFF | 16/07/2017 5:00:00 
    ON | OFF | 16/07/2017 6:00:00 
    ON | ON | 16/07/2017 7:00:00 
    ON | OFF | 16/07/2017 9:00:00 

在這裏總的導通時間爲2小時(3至4 - > 1小時,它仍然爲ON,直到5,從而總的導通時間爲2小時),並兩個狀態再次打開在7和Dgstatus關閉在9,所以這裏總開啓時間是2小時。

最後得總時間爲4小時

有人可以給查詢的SQL Server 2012?

+0

用您正在使用的SQL Server版本標記您的問題。 –

+0

你嘗試過什麼嗎? – JFPicard

+0

@JFPicard,其實我不是新來的sql。 –

回答

0

如果您可以將每個ONOFF減少爲一行,則聚合可以解決問題。你可以做到這一點使用行號的方法的區別:

select ebstatus, dgstatus, 
     min(readtime) as min_rt, max(readtime) as max_rt 
from (select t.*, 
      row_number() over (partition by ebstatus order by readtime) as seqnum_d, 
      row_number() over (partition by ebstatus, dgstatus partition by readtime) as seqnum_sd 
     from t 
    ) t 
group by ebstatus, dgstatus, (seqnum_sd - seqnum_d); 

由此看來,你可以得到總計:

select sum(datediff(hour, min_rt, next_min_rt)) as on_hours 
from (select ebstatus, dgstatus, 
      min(readtime) as min_rt, max(readtime) as max_rt, 
      lead(min(readtime)) over (partition by ebstatus, dgstatus order by min(readtime)) as next_min_rt 
     from (select t.*, 
        row_number() over (partition by ebstatus order by readtime) as seqnum_d, 
        row_number() over (partition by ebstatus, dgstatus partition by readtime) as seqnum_sd 
      from t 
      ) t 
     group by ebstatus, dgstatus, (seqnum_sd - seqnum_d) 
    ) t 
where dgstatus = 'ON' and ebstatus = 'ON'; 
+0

非常感謝。2008年服務器如何實現同樣的功能? –

0

LAG可以檢查以前行,以便您可以檢查的變化dgstatus v alue

SET DATEFORMAT DMY; 
DECLARE @Mytable table (Ebstatus varchar(2), dgstatus varchar(3), ReadTime smalldatetime) 

INSERT @Mytable VALUES 
    ('ON', 'ON ', '16/07/2017 3:00:00'), 
    ('ON', 'ON ', '16/07/2017 4:00:00'), 
    ('ON', 'OFF', '16/07/2017 5:00:00'), 
    ('ON', 'OFF', '16/07/2017 6:00:00'), 
    ('ON', 'ON ', '16/07/2017 7:00:00'), 
    ('ON', 'OFF', '16/07/2017 9:00:00'); 

SELECT 
    SUM(Hours) 
FROM 
    (
    SELECT 
     *, 
     Hours = CASE 
        WHEN 
         Ebstatus = 'ON' AND 
         dgstatus = 'OFF' AND --may be needed to ensure we only count OFF rows 
         LAG(dgstatus) OVER (ORDER BY ReadTime) <> dgstatus 
        THEN 
         DATEDIFF(HOUR, LAG(ReadTime) OVER (ORDER BY ReadTime), ReadTime) 
        ELSE 0 END 
    FROM 
     @Mytable 
    ) X;