1

我不确定这是否可以做到,但如果可以:

假设我有一个简单的表,它有一个时间字段(为简单起见,我们将只使用整数)和一个活动字段。数据可以按时排序。例如:

| 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 文件中,我想我可以编写一个查询来快速为我提供我正在寻找的相同数据。数据不必采用我在下面列出的确切格式,而是给我所有类似活动发生的所有开始/停止时间......

4

2 回答 2

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'

于 2013-03-09T09:33:51.787 回答
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

性能提示:确保你有活动指数

于 2013-03-09T08:12:48.870 回答