我不确定是否可以这样做,但如果可以的话:
假设我有一个简单的表,它有一个时间字段(为简单起见,我们只使用整数)和一个活动字段。数据可以按时分类。例如:
| 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文件中,我想我会写一个查询来快速给出我想要的相同数据。数据不必具有我在下面列出的确切格式,而是给出所有类似活动的所有开始/停止时间......
答案 0 :(得分: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
子查询计算)是具有最小时间戳但仍具有不同活动的记录。
在表的末尾,没有下一组; ifnull
将NULL
转换为字符串'inf'
,其比较大于任何数字。
答案 1 :(得分: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
表现提示:确保你有活动指数