ВЫБРАТЬ, показывая разницу между записями - PullRequest
0 голосов
/ 29 июня 2018

Я бегу PostgreSQL 9.6.

У меня есть таблица записей о вызовах, которая показывает, сколько людей говорили по VOIP строке.

Имеет структуру:

table: voice_records

session_id | user_id | total_seconds_talked

Я получаю записи каждые 1-30 минут или около того, поэтому, если пользователь разговаривает в течение часа, я получу несколько записей для этого одного звонка. Все записи для одного сеанса будут содержать одинаковые session_id, user_id, но с приращением total_seconds_talked.

Ex.

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, где я вижу записи как отдельные записи, поэтому для приведенного выше примера я получу разницу между записями - и, поскольку это VIEW, его следует вычислять на ходу, поэтому получение неправильного порядка корректируется при SELECT VIEW.

Ex.

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

Полагаю, это что-то вроде SELECT с ORDER BY и LIMIT 1, но я действительно застрял на том, как сделать это правильно и наиболее эффективно. А также, какие INDEX должны быть на месте.

UPDATE

Пример просто SELECT:

 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 Ответ

0 голосов
/ 29 июня 2018

Вы, очевидно, хотите 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;

Исходя из вашего описания, значения могут изменяться для выполняющихся вызовов, поскольку записи не принимаются по порядку.

EDIT:

Если по какой-либо причине вы не можете использовать форму с тремя аргументами lag(), просто используйте 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...