如何获取sqlite表中的数据组范围

时间:2013-03-09 07:26:55

标签: java android 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 个答案:

答案 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子查询计算)是具有最小时间戳但仍具有不同活动的记录。 在表的末尾,没有下一组; ifnullNULL转换为字符串'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

表现提示:确保你有活动指数