【问题标题】:Complex SQL query by pattern with timestamps带有时间戳的复杂 SQL 查询
【发布时间】:2020-07-22 12:19:22
【问题描述】:

我的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 是一组符合以下要求的有序寄存器:

  1. 第一个元素大于零。
  2. 第一个元素的前一个元素为零。
  3. 最后一个元素大于零。
  4. 最后一个元素的下一个元素为零。

本例中查询的预期结果是这样的:

[

[{"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}]

]

目前,我正在避免这个查询,我正在使用一个辅助表来存储剧集的初始和结束时间戳,但这只是因为我不知道如何执行这个查询。

因此,我的问题非常简单:有谁知道我如何执行此查询以获得类似于所述输出的内容?

【问题讨论】:

  • 你要返回什么?

标签: sql sqlite timestamp


【解决方案1】:

此答案假定“之前”和“之后”条件并不重要。也就是说,一个剧集可以是表中的第一行。

您可以通过计算每行前0s 的数量来识别剧集。然后过滤掉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;

【讨论】:

    【解决方案2】:

    如果您希望结果为 JSON 对象,则必须使用 SQLite 的 JSON1 Extension 函数:

    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
    

    请参阅demo
    结果:

    | 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}]                                                                                                                                                              |
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-16
      • 2020-07-10
      • 1970-01-01
      • 2015-12-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多