【问题标题】:How to calculate interval between records of one table in PostgreSQL?如何计算PostgreSQL中一张表的记录之间的间隔?
【发布时间】:2020-03-27 19:40:35
【问题描述】:

我的数据示例(表格按 createdAt 列排序):

 id | eventType |         createdAt          
----+-----------+----------------------------
  1 | login     | 2020-03-23 04:05:33.839+00
  2 | login     | 2020-03-23 07:52:55.684+00
  3 | login     | 2020-03-23 11:16:01.243+00
  4 | login     | 2020-03-23 11:34:28.91+00
  5 | login     | 2020-03-23 12:18:21.451+00
  6 | login     | 2020-03-23 13:03:54.742+00
  7 | logout    | 2020-03-23 18:23:26.815+00
  8 | login     | 2020-03-23 20:36:21.972+00
  9 | logout    | 2020-03-23 20:59:58.917+00
 10 | login     | 2020-03-24 04:18:20.432+00
 11 | login     | 2020-03-24 05:44:47.278+00
 12 | logout    | 2020-03-24 10:45:15.463+00
 13 | logout    | 2020-03-24 15:21:55.65+00
 14 | logout    | 2020-03-24 15:48:31.247+00
 15 | login     | 2020-03-24 16:33:23.735+00
 16 | logout    | 2020-03-24 17:07:59.192+00
 17 | logout    | 2020-03-24 18:15:03.661+00
 18 | login     | 2020-03-24 18:29:22.68+00
 19 | logout    | 2020-03-25 01:25:48.345+00
 20 | logout    | 2020-03-25 03:33:26.909+00
 21 | login     | 2020-03-25 10:20:54.3+00

如何计算每对login-logout的时间间隔?

例如。 ID为1的记录和ID为7的记录是第一对login-logout。 ID为8的记录和ID为9的记录是第二对login-logout等等。

某些登录/注销可能没有配对。

我的 PostgreSQL 版本是 11。

【问题讨论】:

  • 同时指定预期结果。 (也许您不需要那么多行样本数据?)
  • 你怎么知道哪个ID是登录-注销对?例如,为什么 ID 9 是 ID 8 而不是 ID 2 的注销?

标签: sql postgresql window-functions


【解决方案1】:

对于每次登录,您都需要下一次注销。使用累积最大值:

select sum(logout - login)
from (select createdAt as login,
             min(createdAt) filter (where eventType = 'logout') over (order by createdAt desc) as logout,
             lag(eventType) over (order by createdAt) as prev_eventType
      from t
     ) t
where eventType = 'login' and
      eventType is distinct from prev_eventType

【讨论】:

    【解决方案2】:

    像这样自加入表

       select t1.id, t2.id from mytable t1 
       left join mytable t2 
       on t1.id+1 = t2.id 
       and t1.eventType = t2.eventType
       where t2.id is null
    

    获取有效行为

    1
    7
    8
    9
    10
    12
    

    在第二步中减去createdAt 的连续行。

    【讨论】:

    • 如果 ID 是连续的,这将中断
    • 你有例子吗?
    • 由于id是主键,所以序列中不会有空缺。
    • 但您也可以按idcreatedAt 排序以获得有效的row-num-id
    猜你喜欢
    • 2015-11-06
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多