【问题标题】:Duration of each status PostgreSQL每个状态的持续时间 PostgreSQL
【发布时间】:2021-12-31 22:29:07
【问题描述】:

我有一张表,每张票都有几个状态 - 例如:

  • 已打开
  • 关闭
  • 重新打开
  • 完成
  • 拒绝
  • ...

状态表中的每一行都有设置/更改状态的时间戳,如下所示:

time status
2021-11-22 09:40 OPENED
2021-11-22 09:50 CLOSED
2021-11-22 10:10 RE-OPENED
2021-11-22 10:30 FINISHED
2021-11-22 10:50 CLOSED
2021-11-22 11:30 RE-OPENED
2021-11-22 12:10 REJECTED

我感兴趣的是如何计算一个时间范围内每个状态的持续时间? 时间范围可以从一小时到几天不等。让我们举个例子,尝试计算每个状态之间的持续时间

2021-11-22 10:00 - 2021-11-22 11:00

如果我们看一下表格:

time status
2021-11-22 09:50 CLOSED
2021-11-22 10:10 RE-OPENED
2021-11-22 10:30 FINISHED
2021-11-22 10:50 CLOSED
2021-11-22 11:30 RE-OPENED
10:00 - 10:10 --> CLOSED
10:10 - 10:30 --> RE-OPENED
10:30 - 10:50 --> FINISHED
10:50 - 11:00 --> CLOSED

结果表如下所示:

status duration
OPENED 00:00
CLOSED 00:20
RE-OPENED 00:20
REJECTED 00:00
FINISHED 00:20

附:如您所见,即使时间范围(10:00 - 11:00)中状态条目的第一次出现是在 10:10,我们必须在所选/所需时间范围之前包含最后报告的状态。

感谢您的帮助。

【问题讨论】:

    标签: postgresql status duration


    【解决方案1】:

    您可以使用 LEAD() 计算满足时间范围条件的行的时间差。然后将时间差相加为持续时间。当您的时间范围跨越几个小时或几天时,这很有帮助。

    WITH calc_table AS (
               SELECT *, LEAD(CASE WHEN t1.time between 
               '2021-11-22 10:00' AND '2021-11-22 11:00' 
               THEN t1.time END) OVER (Order by t1.time) - t1.time as timediff
    FROM mytable t1
    )
    SELECT DISTINCT c.status, 
           SUM(CASE WHEN c.timediff IS NOT NULL THEN c.timediff ELSE '00:00:00' END) AS duration
    FROM calc_table c
    GROUP BY c.status;
    

    Demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-22
      • 1970-01-01
      • 2021-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多