2013-03-09 20 views
1

我不知道,如果可以做到這一點,但如果它能夠:如何獲得數據的羣體範圍在SQLite表

假設我有,有一個時間字段的簡單表(爲簡單起見,我們」只是使用整數)和一個活動領域。數據可以按時排序。例如:

| time | activity 
-------------------- 
| 1 | sitting 
| 3 | sitting 
| 5 | sitting 
| 9 | running 
| 10 | running 
| 11 | sitting 
| 13 | sitting 
| 15 | walking 
| 18 | walking 
| 20 | running 
| 31 | sitting 
| 32 | sitting 

是否有一種簡單的方法來獲取每個活動的開始/停止時間列表?因此,我的結果將是:

sitting (1, 5) 
sitting (9, 10) 
sitting (11, 13) 
running (9, 10) 
running (20, 20) 
walking (15, 18) 

我知道我可以做一個貪婪搜索,併爲每個活動,收集開始/停止時間每一個獨特的集羣和存儲他們的方式。但是,因爲這些數據存儲在一個sqlite文件中,所以我想可能會有一個查詢我可以寫,以便快速給我提供我正在查找的相同數據。該數據並不一定是確切的格式,下面我列出它,而是給我所有的開始/停止時間的活動,像所有出現...

回答

2

SQL是一種面向集合的語言,所以查詢,一邊工作,不漂亮:

SELECT activity, 
     time AS start_time, 
     (SELECT MAX(a3.time) 
     FROM activity AS a3 
     WHERE a3.time < ifnull((SELECT MIN(time) 
           FROM activity AS a4 
           WHERE a4.time > a1.time 
            AND a4.activity != a1.activity), 
           'inf') 
     ) AS end_time 
FROM activity AS a1 
WHERE (SELECT a2.activity 
     FROM activity AS a2 
     WHERE a2.time < a1.time 
     ORDER BY a2.time DESC 
     LIMIT 1 
    ) IS NOT a1.activity 

工作原理:

外部查詢(a1)爲組的每個開始返回記錄。 記錄是組的開始,如果它是具有活動的第一個記錄,即,如果先前記錄具有不同的活動。 以前的記錄是最大時間仍然較小的記錄,並且由a2子查詢計算。 比較使用IS NOT而不是!=,因爲如果沒有以前的記錄,子查詢將返回NULL

第三列由a3子查詢計算得出該組的結束時間。 該組的最後一條記錄是下一組第一條記錄之前的最後一條記錄。 下一組的第一條記錄(由a4子查詢計算)是具有最小時間戳的記錄,該時間戳仍然較大,但具有不同的活動。 在表的最後,沒有下一個組; ifnullNULL轉換成比較大於任何數字的字符串'inf'

+0

這真棒,謝謝!最後一個問題,可以修改爲僅顯示範圍內的項目嗎?例如,如果時間大於3?我試圖讓所有的#。時間比我的範圍更大,但是沒有工作.... – WildBill 2013-03-09 16:35:05

+0

什麼時候?開始?結束?長度? – 2013-03-09 19:25:05

+0

我想我的意思是有可能執行與上面相同的查詢,但將查詢限制在ENTIRE表中的某個範圍內。例如,我只對查找時間大於9的所有數據元組子集的範圍感興趣。因此,基本上可以得到與原始查詢相同的結果,但省略了時間戳爲9或更早的任何數據。如果我需要寫一個新問題,我會:) – WildBill 2013-03-09 19:45:45

0
select a1.activity, min(a1.time), max(a2.time) 
from activity as a1 
    inner join activity as a2 on a1.activity = a2.activity 
group by a1.activity 

性能提示:請確保您有活動指數

+0

這將合併由* other *活動中斷的活動的開始/停止時間。 – 2013-03-09 08:52:06

相關問題