2013-01-11 45 views
5

我有一張類似於MS SQL Server中的表。根據組的ID和其他條件的最小值和最大值

 id | Timestamp | active 
    -----+-----------+-------- 
     1 | 1:00 | 1 
     1 | 2:00 | 1 
     1 | 3:00 | 1 
     1 | 4:00 | 0 
     1 | 5:00 | 0 
     1 | 6:00 | 1 
     1 | 7:00 | 0 
     1 | 8:00 | 0 
     1 | 9:00 | 0 
     1 | 10:00 | 1 
     1 | 11:00 | 1 
     1 | 12:00 | 0 
     1 | 13:00 | 1 
     2 | 2:00 | 1 
     2 | 3:00 | 1 
     2 | 4:00 | 0 
     2 | 5:00 | 0 
     3 | 8:00 | 0 
     3 | 9:00 | 0 
     4 | 1:00 | 1 
     4 | 2:00 | 1 
     5 | 16:00 | 0 

我想知道每個ID何時無效(活動= 0)多長時間。我試圖做的是在active = 0時將其按id進行分組,並在最小和最大時間內做一個過時的事情。但是,這會讓我得到id 1的結果,表示它在8小時(12:00 - 4:00)@ 12:00離線。當我真正想要的是一個查詢,會給我下面的結果集。

id | approx. offline in hours | at time 
    ---+--------------------------+----------- 
    1 |   1    | 5:00 
    1 |   2    | 9:00 
    1 |   0    | 12:00 
    2 |   1    | 5:00 
    3 |   0    | 9:00 
    5 |   0    | 16:00 

錯誤的查詢我最初嘗試是

SELECT id as [Inactive], 
     DATEDIFF(hour, MIN(Timestamp), MAX(Timestamp)) as [approx. offline in hours], 
     MAX(Timestamp) as [at time] 
FROM table 
WHERE active = 0 
GROUP BY [Inactive] 

但隨着該查詢的問題是,它跳過主動倍之間。我一直在尋找THIS問題,這個問題已經被問及使用PARTITION回答,但它看起來像問題是不同的,答案是太具體到我無法理解的問題。

任何幫助表示讚賞。

+0

你使用的是什麼rdbms? SQL服務器,甲骨文? – Taryn

+0

@bluefeet方括號最有可能== SQL Server –

+0

@JoachimIsaksson我同意,但他們應該說明他們正在使用的rdbms。 – Taryn

回答

3

解決這個問題的一種方法是在任何數據庫中工作,就是使用相關的子查詢。這個想法是爲每個連續的活動值字符串分配一個組名。特定的組名稱是下一次更改值的時間。

select id, active, min(TimeStamp), max(TimeStamp) 
from (select t.*, 
      (select min(timeStamp) from t t2 where t2.id = t.id and t2.timeStamp > t.timeStamp and t2.active <> t.active 
      ) groupName 
     from t 
    ) t 
group by id, groupName, active 

一個告誡如何讓時間戳變成持續時間取決於數據庫。既然你沒有指定數據庫,我會讓你添加這個邏輯。

此外,如果某個給定ID的最後一條記錄不活動,則組名爲NULL。這不是問題。

+0

我認爲這個答案有一個錯誤,因爲當ID改變 – Bulat

+0

@Bulat時,groupName將爲NULL。 。 。這不是問題。 NULL對於分組有效,並且id包含在「group by」列中。 –

+0

是的,你說得對,這不是問題。您可能只想重命名TimesStamp以使字段名稱保持一致。 http://sqlfiddle.com/#!3/e5831/45/0 – Bulat