近期SQLite分组

时间:2018-02-21 23:25:33

标签: sql sqlite group-by

我有一个像这样的SQLite表:

sqlite> select * from things order by id;
id          created         
----------  ----------------
1           2458171.46967479
2           2458171.46967747
3           2458171.46968049
4           2458171.46968362
5           2458171.46968647
6           2458171.46968948
7           2458171.46969561
8           2458171.46973709
9           2458171.46974006
10          2458171.46974368
11          2458171.46978387

created是一个julianday时间戳。我想选择最近同时记录的最新行组。 "大约在同一时间"在#100;彼此相差100毫秒之内。"

我知道如何将整个表分成谨慎的桶,但我想要的不同之处。例如(并且这与上面的表格不匹配),让我们说最近的记录的时间戳为0.下一个最近的记录的时间戳为+75,最近的第三个记录的时间戳为时间戳为+160。

或换句话说:

id     tstamp
------ -------
156    0
155    75
154    160
  • 如果我的阈值为50,则只返回#156。
  • 如果我的阈值是75,那么应该返回#156和#155。
  • 如果我的阈值是85,则应返回所有三个,因为160在下一个最近一行的85之内。

有关如何进行的任何建议?我可以在应用程序代码中完成它,但如果可以的话,它在SQL中要快得多。我怀疑我可能需要用WITH RECURISIVE做一些事情吗?

1 个答案:

答案 0 :(得分:2)

阅读WITH RECURSIVE文档之后:https://www.sqlite.org/lang_with.html

这是我的解决方案:

WITH RECURSIVE
    what(x) AS (
        SELECT max(created) FROM things
        UNION
        SELECT things.created FROM what, things
        WHERE things.created >= (what.x - 85)
    )
SELECT x FROM what ORDER BY 1;

这里有一些示例查询显示它有效:

sqlite> select * from things;
id          created   
----------  ----------
1           160       
2           85        
3           0         

sqlite> WITH RECURSIVE
   ...>     what(x) AS (
   ...>         SELECT max(created) FROM things
   ...>         UNION
   ...>         SELECT things.created FROM what, things
   ...>         WHERE things.created >= (what.x - 50)
   ...>     )
   ...> SELECT x FROM what ORDER BY 1;
x         
----------
160       

sqlite> WITH RECURSIVE
   ...>     what(x) AS (
   ...>         SELECT max(created) FROM things
   ...>         UNION
   ...>         SELECT things.created FROM what, things
   ...>         WHERE things.created >= (what.x - 75)
   ...>     )
   ...> SELECT x FROM what ORDER BY 1;
x         
----------
85        
160       

sqlite> WITH RECURSIVE
   ...>     what(x) AS (
   ...>         SELECT max(created) FROM things
   ...>         UNION
   ...>         SELECT things.created FROM what, things
   ...>         WHERE things.created >= (what.x - 85)
   ...>     )
   ...> SELECT x FROM what ORDER BY 1;
x         
----------
0         
85        
160