在postgresql中将重复的连续事件计数为组

Posted

技术标签:

【中文标题】在postgresql中将重复的连续事件计数为组【英文标题】:Count repeating consecutive events as groups in postgresql 【发布时间】:2021-12-28 15:38:16 【问题描述】:

我有一个 PostgreSQL 数据集,其中包含员工姓名、入职 ID 和入职时间。根据员工打卡的次数,这些内容会在多行中重复。我要做的是对每个员工的连续条目进行分组并计算条目数。

输入

entry_id    emp_name        entry_time
100         John Doe        18/10/2021
101         Mark Foo        18/10/2021
102         Angie Genie     19/10/2021
103         Angie Genie     19/10/2021
104         Angie Genie     19/10/2021
105         John Doe        20/10/2021
106         John Doe        20/10/2021
107         Angie Genie     21/10/2021
108         Angie Genie     21/10/2021
109         Mark Foo        22/10/2021
110         Mark Foo        22/10/2021
111         Mark Foo        23/10/2021
112         Mark Foo        24/10/2021

期望的输出

emp_name            last entry_time     no of entries
John Doe            18/10/2021          1
Mark Foo            18/10/2021          1
Angie Genie         19/10/2021          3
John Doe            20/10/2021          2
Angie Genie         21/10/2021          2
Mark Foo            24/10/2021          4

我尝试使用间隙和孤岛方法将连续的 emp_names 分配到组中,以使我能够获得条目计数,但我无法这样做。我希望分配如下组,但到目前为止没有任何效果。

entry_id        emp_name            entry_time          group       no of entries
100             John Doe            18/10/2021          1           1
101             Mark Foo            18/10/2021          2           1
102             Angie Genie         19/10/2021          3           3
103             Angie Genie         19/10/2021          3           3
104             Angie Genie         19/10/2021          3           3
105             John Doe            20/10/2021          4           2
106             John Doe            20/10/2021          4           2
107             Angie Genie         21/10/2021          5           2
108             Angie Genie         21/10/2021          5           2
109             Mark Foo            22/10/2021          6           4
110             Mark Foo            22/10/2021          6           4
111             Mark Foo            23/10/2021          6           4
112             Mark Foo            24/10/2021          6           4

这在 PostgreSQl 中可行吗?任何帮助表示赞赏。 谢谢。

【问题讨论】:

【参考方案1】:

您可以使用窗口函数LAG()检查每一行的前一个emp_name,并使用窗口函数SUM()创建连续重复的组emp_names。 最后按每组汇总:

SELECT emp_name, 
       MAX(entry_time) last_entry_time,
       COUNT(*) no_of_entries 
FROM (
  SELECT *, SUM(flag) OVER (ORDER BY entry_time, entry_id) grp
  FROM (
    SELECT *, (emp_name <> LAG(emp_name, 1, '') OVER (ORDER BY entry_time, entry_id))::int flag
    FROM tablename
  ) t
) t
GROUP BY grp, emp_name
ORDER BY grp;

请参阅demo。

【讨论】:

哇,非常感谢!它完美地工作。再次感谢。 嗨,forpas,您能否解释一下这部分代码,以便我了解如何计算标志。 (emp_name LAG(emp_name, 1, '') OVER (ORDER BY entry_time, entry_id))::int flag @OkechukwuOssai 一步一步检查代码可能更容易:dbfiddle.uk/… 如果 emp_name 与前一个不同,则第一个子查询在每一行中返回 1。第二个子查询对 1 求和并创建重复名称组。 谢谢forpas。我最初想知道这部分代码在做什么(emp_name LAG(emp_name, 1, '')。但我现在明白了。谢谢。

以上是关于在postgresql中将重复的连续事件计数为组的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL数组 - 删除连续相同的值[重复]

在postgresql中将值提取到逗号分隔的字符串中[重复]

在java中将时间戳转换为日期并显示计数值[重复]

PostgreSQL查询:编写查询返回每组连续数字的最大值[重复]

如何在 SQL 视图中将计数和总和组表示为列?

为组中的每个案例选择一个非重复控件