У меня есть таблица журнала, в которой хранятся события в виде
timestamp, object_id, state
2018-08-12 13:45 123 10
2018-08-13 15:56 183 25
2018-08-13 15:58 123 10
2018-08-15 16:02 256 15
Существует первичный ключ (не включенный для краткости), отметка времени - это поле даты и времени, object_id - это отношение ключа foregn к разностной таблице, а состояние - целое число в диапазоне 0-100. События записываются по мере их поступления, и состояние не обязательно меняется между событиями, поэтому один и тот же object_id может иметь несколько последовательных записей с одним и тем же состоянием.
База данных PostgreSQL 9.5
То, что я пытаюсь сделать, это вычислить среднее состояние для месячных, дневных и недельных интервалов для отдельных объектов или объектов, выбранных по некоторым критериям. Результаты, которые я ожидаю получить для среднесуточных значений, должны выглядеть примерно так:
date, object_id, average state
2018-08-12 123 18.6
2018-08-13 123 37.1
2018-08-14 123 126.7
2018-08-15 123 5.5
где среднее состояние вычисляется взвешенным по количеству времени, которое объект провел в каждом данном состоянии в течение интервала (в случае выше, в течение одного дня) с интервалами в одну минуту, так что если объект проводит 23 часа в состоянии 10, но 15 минут в состоянии 50, среднее значение должно составлять
15/1440 * 50 + 1425/1440 * 10 = 10.42
До сих пор мне удавалось использовать оконные функции для преобразования отдельных событий в интервалы между изменениями состояния. SQL выглядит примерно так
SELECT
state.object_id,
state.timestamp as start,
lead(timestamp) OVER (ORDER BY timestamp) as end,
state.state,
FROM
(
SELECT
*,
rank() OVER (PARTITION BY (state) ORDER BY timestamp)
FROM event_log AS l
WHERE object_id=123 AND timestamp >= DATE '2018-01-01'
) AS state
WHERE state.rank=1
ORDER BY timestamp
и получите вывод, который дает мне начало и конец интервалов, когда состояние действительно меняется. Я не уверен, куда идти отсюда. События не всегда происходят часто, поэтому у меня может быть интервал, который длится три дня, и мне как-то нужно сообщать об этом изо дня в день, поэтому мне нужно разделить этот интервал на дни. Как мне поступить правильно?