SQL для расчета времени просмотра для каждого просмотра из журнала просмотра видео - PullRequest
0 голосов
/ 19 июня 2019

Существует таблица, в которой хранятся следующие данные журнала просмотра видео.

|user_id| status |     time         |
-------------------------------------
|user_a |start   |2019-06-18 00:00:00|
|user_a |progress|2019-06-18 00:00:05|
|user_a |progress|2019-06-18 00:00:10|
|user_a |complete|2019-06-18 00:00:15|
|user_a |start   |2019-06-18 00:10:00|
|user_a |complete|2019-06-18 00:10:05|
|user_b |start   |2019-06-18 00:20:00|
|user_b |progress|2019-06-18 00:20:05|
|user_b |progress|2019-06-18 00:20:10|

Из приведенной выше таблицы я хотел бы рассчитать, сколько секунд каждое видео было просмотрено для просмотра каждым пользователем.

Изображение ниже.

|user_id|views_num|time(second) |
|user_a |1        |15           |
|user_a |2        |5            |
|user_b |1        |10           |

Журналы записываются каждые 5 секунд.

Есть ли способ агрегирования с sql?

Я использую Presto.

1 Ответ

1 голос
/ 19 июня 2019

Ожидаемый результат может быть достигнут снизу.

Использование подзапроса в качестве выражения столбца в той же таблице

SELECT t.user AS "user_id"
    ,row_number() OVER (
        PARTITION BY t.user ORDER BY TIME
        ) AS "views_num"
    ,EXTRACT(EPOCH FROM (COALESCE(t.complete, t.progress) - t.TIME)) AS "time(second)"
FROM (
    SELECT *
        ,(
            SELECT min(TIME)
            FROM log l2
            WHERE l1.user = l2.user
                AND l2.STATUS = 'complete'
                AND l1.TIME < l2.TIME
            ) complete
        ,(
            SELECT max(TIME)
            FROM log l3
            WHERE l1.user = l3.user
                AND l3.STATUS = 'progress'
                AND l1.TIME < l3.TIME
            ) progress
    FROM log l1
    WHERE l1.STATUS = 'start'
    ) t

DEMO

выход

| user_id | views_num | time(second) |
| ------- | --------- | ------------ |
| user_a  | 1         | 15           |
| user_a  | 2         | 5            |
| user_b  | 1         | 10           |

В PrestoDB используйте date_diff вместо EXTRACT(EPOCH()), который используется в postgre. Демо использует Postgre DB. Вы можете изменить строку, как показано ниже, и она должна работать.

date_diff('second', COALESCE(t.complete, t.progress),t.TIME) AS "time(second)"

prestosql date_diff

...