按带时间戳的模式的复杂sql查询

cunj1qz1  于 2021-07-24  发布在  Java
关注(0)|答案(2)|浏览(295)

我的电脑里有以下信息 SQLite 数据库:

ID | timestamp  | val
1  | 1577644027 | 0
2  | 1577644028 | 0
3  | 1577644029 | 1
4  | 1577644030 | 1
5  | 1577644031 | 2
6  | 1577644032 | 2
7  | 1577644033 | 3
8  | 1577644034 | 2
9  | 1577644035 | 1
10 | 1577644036 | 0
11 | 1577644037 | 1
12 | 1577644038 | 1
13 | 1577644039 | 1
14 | 1577644040 | 0

我想执行一个查询,返回组成 episode . 一 episode 是一组符合以下要求的有序寄存器:
第一个元素大于零。
第一个元素的前一个元素是零。
最后一个元素大于零。
最后一个元素的下一个元素是零。
本例中查询的预期结果如下:

[

[{"id":3, tmstamp:1577644029, value:1}
{"id":4, tmstamp:1577644030, value:1}
{"id":5, tmstamp:1577644031, value:2}
{"id":6, tmstamp:1577644032, value:2}
{"id":7, tmstamp:1577644033, value:3}
{"id":8, tmstamp:1577644034, value:2}
{"id":9, tmstamp:1577644035, value:1}],

[{"id":11, tmstamp:1577644037, value:1}
{"id":12, tmstamp:1577644038, value:1}
{"id":13, tmstamp:1577644039, value:1}]

]

目前,我正在避免这个查询,并使用一个辅助表来存储剧集的初始和结束时间戳,但这只是因为我不知道如何执行这个查询。
首先,我的问题很简单:有人知道我如何执行这个查询以获得类似于所述输出的东西吗?

xpcnnkqh

xpcnnkqh1#

如果要将结果作为json对象,则必须使用sqlite的json1扩展函数:

with cte as (
  select *, sum(val = 0) over (order by timestamp) grp
  from tablename
) 
select 
  json_group_array(
    json_object('id', id, 'timestamp', timestamp, 'val', val)
  ) result
from cte
where val > 0
group by grp

请看演示。
结果:

| result                                                                                                                                                                                                                                                                                    |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [{"id":3,"timestamp":1577644029,"val":1},{"id":4,"timestamp":1577644030,"val":1},{"id":5,"timestamp":1577644031,"val":2},{"id":6,"timestamp":1577644032,"val":2},{"id":7,"timestamp":1577644033,"val":3},{"id":8,"timestamp":1577644034,"val":2},{"id":9,"timestamp":1577644035,"val":1}] |
| [{"id":11,"timestamp":1577644037,"val":1},{"id":12,"timestamp":1577644038,"val":1},{"id":13,"timestamp":1577644039,"val":1}]                                                                                                                                                              |
kpbwa7wx

kpbwa7wx2#

这个答案假设“之前”和“之后”条件并不重要。也就是说,一集可以是表中的第一行。
你可以通过数一数 0 在每行前面加一个字母。然后过滤掉 0 价值观:

select t.*,
       dense_rank() over (order by grp) as episode
from (select t.*,
             sum(case when val = 0 then 1 else 0 end) over (order by timestamp) as grp
      from t
     ) t
where val <> 0;

如果不是这样,那么 lag() 以及 lead() 累积和可以处理前面的值 0 :

select t.*,
       sum(case when prev_val = 0 and val > 0 then 1 else 0 end) over (order by timestamp) as episode
from (select t.*,
             lag(val) over (order by timestamp) as prev_val,
             lead(val) over (order by timestamp) as next_val
      from t
     ) t
where val <> 0;

相关问题