【问题标题】:How to select subseqent pairs from one table如何从一个表中选择后续对
【发布时间】:2018-10-04 11:57:24
【问题描述】:

我有一个表格,其中包含来自多个传感器的数据。当传感器上发生特殊事件时添加行。 Sensor 的事件序列号始终在增长,并且不能小于先前事件的序列号,但不能保证它以恒定值增长。它可能是1, 2, 5,6, 11,... 的序列。每行包含传感器 ID、事件序列号、事件发生时的时间戳和一些数据。我想获得按时间戳排序的每个传感器的后续事件对。

带有一些虚拟数据的表结构示例:

CREATE TABLE event (
  sensor_id  INT,
  event_seq INT,
  ts        INT,
  data      TEXT,
  CONSTRAINT event_pk PRIMARY KEY (sensor_id, event_seq)
);

INSERT INTO event (sensor_id, event_seq, ts, data) VALUES
  (1, 1, 1, '1st sensor 1st event'),
  (1, 2, 2, '1st sensor 2nd event'),
  (2, 1, 2, '2nd sensor 1st event'),
  (2, 2, 3, '2nd sensor 2nd event'),
  (1, 3, 3, '1st sensor 3rd event'),
  (1, 4, 4, '1st sensor 4th event'),
  (2, 3, 5, '2nd sensor 3rd event'),
  (1, 5, 5, '1st sensor 5th event'),
  (2, 4, 6, '2nd sensor 4th event'),
  (2, 5, 7, '2nd sensor 5th event'),
  (1, 6, 7, '1st sensor 6th event');

目前,我使用 SQLite DB。我想出了以下查询:

SELECT
  a.data,
  a.ts,
  b.data,
  b.ts
FROM event AS a
  JOIN event AS b ON a.sensor_id = b.sensor_id AND a.event_seq < b.event_seq
GROUP BY a.sensor_id, a.event_seq
HAVING min(b.event_seq)
ORDER BY a.ts, b.ts

它实际上提供了我需要的结果 (SQL Fiddle):

|                 data | ts |                 data | ts |
|----------------------|----|----------------------|----|
| 1st sensor 1st event |  1 | 1st sensor 2nd event |  2 |
| 1st sensor 2nd event |  2 | 1st sensor 3rd event |  3 |
| 2nd sensor 1st event |  2 | 2nd sensor 2nd event |  3 |
| 1st sensor 3rd event |  3 | 1st sensor 4th event |  4 |
| 2nd sensor 2nd event |  3 | 2nd sensor 3rd event |  5 |
| 1st sensor 4th event |  4 | 1st sensor 5th event |  5 |
| 2nd sensor 3rd event |  5 | 2nd sensor 4th event |  6 |
| 1st sensor 5th event |  5 | 1st sensor 6th event |  7 |
| 2nd sensor 4th event |  6 | 2nd sensor 5th event |  7 |

但我在HAVING 中使用min 函数,没有任何返回布尔值的表达式。它可以工作,但根据文档,它应该是布尔表达式,所以我不知道我是否遗漏了什么,或者这是错误或其他什么。 此外,有可能有一天我需要切换到 PostgreSQL,而这个查询实际上在 Postgres 上出错argument of HAVING must be type boolean, not type integer Position: 177

所以我的问题是如何编写这个查询,以便它同时适用于 SQLite 和 Postgres。 另外,有什么索引可以加快查询速度的建议吗?

【问题讨论】:

    标签: sql postgresql sqlite


    【解决方案1】:

    (我对 Stackoverflow 的第一条评论,要温柔 :-)

    以下查询是实现相同目的的不同方式。我不确定(完全)它是否更快。在 PostgreSQL 上,您肯定会求助于窗口函数 LEAD 或 LAG,它们应该会执行得更好。

    SELECT
      a.data,
      a.ts,
      b2.data,
      b2.ts
    FROM event AS a
      JOIN (select b.sensor_id, b.data, b.ts 
        from event AS b 
        where a.sensor_id = b.sensor_id
        AND a.event_seq < b.event_seq
        order by event_seq DESC
        limit 1 ) b2
    on b2.sensor_id = a.sensor_id
    

    【讨论】:

    • 对我不起作用。 Error: no such column: a.sensor_id
    【解决方案2】:

    如果我理解正确,您可以将JOIN 与相等条件一起使用:

    SELECT a.data, a.ts, b.data, b.ts
    FROM event a JOIN
         event b
         ON a.sensor_id = b.sensor_id AND a.event_seq = b.event_seq - 1
    ORDER BY a.ts, b.ts;
    

    【讨论】:

    • 好点。不幸的是,不能保证序列号增加常数值。我更新了我的问题。
    猜你喜欢
    • 2011-11-05
    • 1970-01-01
    • 1970-01-01
    • 2013-12-23
    • 1970-01-01
    • 2021-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多