代码之家  ›  专栏  ›  技术社区  ›  Alfred Balle

显示记录差异时选择

  •  1
  • Alfred Balle  · 技术社区  · 6 年前

    我在跑步 PostgreSQL 9.6 .

    我有一张通话记录表,上面显示了有多少人在 VOIP 行。

    它具有以下结构:

    table: voice_records
    
    session_id | user_id | total_seconds_talked
    

    我每隔1-30分钟左右会收到一个记录,所以如果一个用户通话一个小时,我会收到一次通话的多个记录。 单个会话的所有记录将包含相同的 session_id ,请 user_id 但不断增加 total_seconds_talked .

    前任。

    234gdd-542-vffd, 1001, 5
    234gdd-542-vffd, 1001, 11
    234gdd-542-vffd, 1001, 532
    234gdd-542-vffd, 1001, 234
    234gdd-542-vffd, 1001, 1159
    

    重要的是要知道,我可能会收到错误的顺序记录。

    我想创建一个 VIEW 我把这些记录看作是不可分割的记录, 所以在上面的例子中,我会得到记录之间的区别,因为它是 视图 它应该在运行时计算,因此当收到错误的订单时 SELECT 视图 .

    前任。

    SELECT * FROM voice_records WHERE session_id = '234gdd-542-vffd'
    
    OUTPUT:
    
    234gdd-542-vffd, 1001, 5
    234gdd-542-vffd, 1001, 6
    234gdd-542-vffd, 1001, 223
    234gdd-542-vffd, 1001, 298
    234gdd-542-vffd, 1001, 627
    

    我想这涉及到某种 选择 有一个 ORDER BY LIMIT 1 但我真的有点执着于如何正确地、最有效地做到这一点。 以及 INDEX ES应到位。

    更新

    简单的例子 选择 以下内容:

     user_id |   session_id    | seconds_this_time
    ---------+-----------------+--------
     1001    | 234gdd-542-vffd | 313557
     1001    | 234gdd-542-vffd | 314844
     1001    | 234gdd-542-vffd | 338980
     1001    | 234gdd-542-vffd | 507246
     1001    | 234gdd-542-vffd | 509233
     1001    | 234gdd-542-vffd | 509441
     1001    | 234gdd-542-vffd | 553260
     1001    | 234gdd-542-vffd | 556985
     1001    | 234gdd-542-vffd | 581958
     1001    | 234gdd-542-vffd | 586079
     1001    | 234gdd-542-vffd | 597381
     1001    | 234gdd-542-vffd | 597745
     1001    | 234gdd-542-vffd | 611672
     1001    | 234gdd-542-vffd | 709918
     1001    | 234gdd-542-vffd | 725510
     1001    | 234gdd-542-vffd | 743432
     1001    | 234gdd-542-vffd | 743835
     1001    | 234gdd-542-vffd | 743835
     1001    | 234gdd-542-vffd |
    

    lag 功能:

     user_id |   session_id    | seconds_this_time
    ---------+-----------------+--------
     1001    | 234gdd-542-vffd |
     1001    | 234gdd-542-vffd |   1287
     1001    | 234gdd-542-vffd |  24136
     1001    | 234gdd-542-vffd | 168266
     1001    | 234gdd-542-vffd |   1987
     1001    | 234gdd-542-vffd |    208
     1001    | 234gdd-542-vffd |  43819
     1001    | 234gdd-542-vffd |   3725
     1001    | 234gdd-542-vffd |  24973
     1001    | 234gdd-542-vffd |   4121
     1001    | 234gdd-542-vffd |  11302
     1001    | 234gdd-542-vffd |    364
     1001    | 234gdd-542-vffd |  13927
     1001    | 234gdd-542-vffd |  98246
     1001    | 234gdd-542-vffd |  15592
     1001    | 234gdd-542-vffd |  17922
     1001    | 234gdd-542-vffd |    403
     1001    | 234gdd-542-vffd |      0
     1001    | 234gdd-542-vffd |
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   Gordon Linoff    6 年前

    你显然想要 lag() 以下内容:

    select user_id, session_id,
           (total_seconds_talked -
            lag(total_seconds_talked, 1, 0::bigint) over (partition by user_id, session_id order by total_seconds_talked)
           ) as seconds_this_time
    from voice_records;
    

    根据您的描述,正在进行的调用的值可能会更改,因为没有按顺序接收记录。

    编辑:

    如果出于某种原因,您不能使用 滞后() ,只需使用 coalesce() 以下内容:

    select user_id, session_id,
           (total_seconds_talked -
            coalesce(lag(total_seconds_talked) over (partition by user_id, session_id order by total_seconds_talked), 0)
           ) as seconds_this_time
    from voice_records;