sql - 按 T​​imescaleDB/PostgreSQL 中的突发事件分组

标签 sql postgresql timescaledb

这是我在 stackoverflow 中的第一个问题,欢迎任何有关如何提出结构良好的问题的建议。

所以,我有一个 TimescaleDB 数据库,它是基于 Postgres 构建的时间序列数据库。它具有其大部分功能,因此如果您不了解 Timescale,那也不是问题。 我有一个返回的 select 语句:

          time          | num_issues |   actor_login
------------------------+------------+------------------
 2015-11-10 01:00:00+01 |          2 | nifl
 2015-12-10 01:00:00+01 |          1 | anandtrex
 2016-01-09 01:00:00+01 |          1 | isaacrg
 2016-02-08 01:00:00+01 |          1 | timbarclay
 2016-06-07 02:00:00+02 |          1 | kcalmes
 2016-07-07 02:00:00+02 |          1 | cassiozen
 2016-08-06 02:00:00+02 |         13 | phae
 2016-09-05 02:00:00+02 |          2 | phae
 2016-10-05 02:00:00+02 |         13 | cassiozen
 2016-11-04 01:00:00+01 |          6 | cassiozen
 2016-12-04 01:00:00+01 |          4 | cassiozen
 2017-01-03 01:00:00+01 |          5 | cassiozen
 2017-02-02 01:00:00+01 |          8 | cassandraoid
 2017-03-04 01:00:00+01 |         16 | erquhart
 2017-04-03 02:00:00+02 |          3 | erquhart
 2017-05-03 02:00:00+02 |          9 | erquhart
 2017-06-02 02:00:00+02 |          5 | erquhart
 2017-07-02 02:00:00+02 |          2 | greatwarlive
 2017-08-01 02:00:00+02 |          8 | tech4him1
 2017-08-31 02:00:00+02 |          7 | tech4him1
 2017-09-30 02:00:00+02 |         17 | erquhart
 2017-10-30 01:00:00+01 |          7 | erquhart
 2017-11-29 01:00:00+01 |         12 | erquhart
 2017-12-29 01:00:00+01 |          8 | tech4him1
 2018-01-28 01:00:00+01 |          6 | ragasirtahk

它紧随其后。基本上它会在一定时间内返回用户名,在本例中为 30 天。 SQL 查询是:

SELECT DISTINCT ON(time_bucket('30 days', created_at))
  time_bucket('30 days', created_at) as time,
  count(id) as num_issues,
  actor_login
FROM
  issues_event
WHERE action = 'opened' AND repo_name='netlify/netlify-cms'
group by time, actor_login
order by time, num_issues DESC

我的问题是,如何检测或分组具有相同 actor_login 且连续的行。 例如,我想将 cassiozen 从 2016-10-05 到 2017-01-03 分组,但不与列的其他 cassiozen 分组。 我尝试过使用辅助列,使用 LAG 等窗口函数,但如果没有函数或 do 语句,我认为这是不可能的。 我也尝试过函数,但找不到方法。

我们将不胜感激任何方法、想法或解决方案。

编辑:我显示我想要的输出。

          time          | num_issues |   actor_login    | actor_group_id
------------------------+------------+------------------+----------------
 2015-11-10 01:00:00+01 |          2 | nifl             |              0
 2015-12-10 01:00:00+01 |          1 | anandtrex        |              1
 2016-01-09 01:00:00+01 |          1 | isaacrg          |              2
 2016-02-08 01:00:00+01 |          1 | timbarclay       |              3
 2016-06-07 02:00:00+02 |          1 | kcalmes          |              4
 2016-07-07 02:00:00+02 |          1 | cassiozen        |              5
 2016-08-06 02:00:00+02 |         13 | phae             |              6
 2016-09-05 02:00:00+02 |          2 | phae             |              6
 2016-10-05 02:00:00+02 |         13 | cassiozen        |              7
 2016-11-04 01:00:00+01 |          6 | cassiozen        |              7
 2016-12-04 01:00:00+01 |          4 | cassiozen        |              7
 2017-01-03 01:00:00+01 |          5 | cassiozen        |              7
 2017-02-02 01:00:00+01 |          8 | cassandraoid     |             12
 2017-03-04 01:00:00+01 |         16 | erquhart         |             13
 2017-04-03 02:00:00+02 |          3 | erquhart         |             13
 2017-05-03 02:00:00+02 |          9 | erquhart         |             13
 2017-06-02 02:00:00+02 |          5 | erquhart         |             13
 2017-07-02 02:00:00+02 |          2 | greatwarlive     |             17
 2017-08-01 02:00:00+02 |          8 | tech4him1        |             18
 2017-08-31 02:00:00+02 |          7 | tech4him1        |             18
 2017-09-30 02:00:00+02 |         17 | erquhart         |             16
 2017-10-30 01:00:00+01 |          7 | erquhart         |             16
 2017-11-29 01:00:00+01 |         12 | erquhart         |             16
 2017-12-29 01:00:00+01 |          8 | tech4him1        |             21
 2018-01-28 01:00:00+01 |          6 | ragasirtahk      |             24

MatBaille 的解决方案几乎是完美的。 我只是想像这样对连续的 Actor 进行分组,这样我就可以提取一堆具有表格其他属性的指标。

最佳答案

您可以使用所谓的“间隙和岛屿”方法

WITH
  sorted AS
(
  SELECT
    *,
    ROW_NUMBER() OVER (                         ORDER BY time)   AS rn,
    ROW_NUMBER() OVER (PARTITION BY actor_login ORDER BY time)   AS rn_actor
  FROM
    your_results
)
SELECT
  *,
  rn - rn_actor  AS actor_group_id
FROM
  sorted

然后 (actor_login, actor_group_id) 的组合将连续的行组合在一起。

db<>fiddle demo

关于sql - 按 T​​imescaleDB/PostgreSQL 中的突发事件分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67482158/

相关文章:

postgresql - 在 Ubuntu : file not found 上更新 TimescaleDB 后出现 Postgres 错误

sql - 如何连接表并根据条件选择重复项

mysql - 一列有 2 行相同的行,我想先显示它

postgresql - 更新记录(如果存在)

postgresql - 如何在没有警告停止的情况下在postgres中执行真空命令?

postgresql - 如何使用 Entity Framework 核心为 postgres 数据库安装 TimescaleDB 扩展

sql - 如何在 T-SQL 中插入另一个表中的列?

sql - 在规范化数据库时从单个表插入多个表

sql - 在 Postgres 中,如何在同一查询中进行 COUNT 和 WHERE,然后对结果进行数学运算?

postgresql - TimescaleDB:具有追加与中点插入和索引的超表的性能