Мне нужно вычислить значение некоторого столбца X на основе некоторых других столбцов текущей записи и значения X для предыдущей записи (с использованием некоторого раздела и порядка). В основном мне нужно реализовать запрос в форме
SELECT <some fields>,
<some expression using LAG(X) OVER(PARTITION BY ... ORDER BY ...) AS X
FROM <table>
Это невозможно, потому что в оконной функции можно использовать только существующие столбцы, поэтому я ищу способ преодолеть это.
Вот пример. У меня есть таблица с событиями. Каждое событие имеет type
и time_stamp
.
create table event (id serial, type integer, time_stamp integer);
Я не хочу находить "повторяющиеся" события (пропустить их). Под дублированием я подразумеваю следующее. Упорядочим все события для данного type
по time_stamp
по возрастанию. потом
- первое событие не повторяется
- все события, которые не повторяются и находятся в пределах некоторого периода времени после него (то есть их
time_stamp
не больше, чемtime_stamp
предыдущего не дублированного плюс некоторая константаTIMEFRAME
), являются дубликатами - следующее событие, которое на
time_stamp
больше, чем предыдущее, не повторяющееся более чем наTIMEFRAME
, не является дубликатом - и так далее
По этим данным
insert into event (type, time_stamp)
values
(1, 1), (1, 2), (2, 2), (1,3), (1, 10), (2,10),
(1,15), (1, 21), (2,13),
(1, 40);
и TIMEFRAME=10
результат должен быть
time_stamp | type | duplicate
-----------------------------
1 | 1 | false
2 | 1 | true
3 | 1 | true
10 | 1 | true
15 | 1 | false
21 | 1 | true
40 | 1 | false
2 | 2 | false
10 | 2 | true
13 | 2 | false
Я мог бы вычислить значение поля duplicate
на основе текущих time_stamp
и time_stamp
предыдущего неповторяющегося события следующим образом:
WITH evt AS (
SELECT
time_stamp,
CASE WHEN
time_stamp - LAG(current_non_dupl_time_stamp) OVER w >= TIMEFRAME
THEN
time_stamp
ELSE
LAG(current_non_dupl_time_stamp) OVER w
END AS current_non_dupl_time_stamp
FROM event
WINDOW w AS (PARTITION BY type ORDER BY time_stamp ASC)
)
SELECT time_stamp, time_stamp != current_non_dupl_time_stamp AS duplicate
Но это не работает, потому что на вычисляемое поле нельзя ссылаться в LAG
:
ERROR: column "current_non_dupl_time_stamp" does not exist.
Итак, вопрос: можно ли переписать этот запрос, чтобы добиться нужного мне эффекта?
the next event which time_stamp if greater than previous non duplicate by more than TIMEFRAME is not duplicate
. таймфрейм - это константа, поле или расчет? - person Jorge Campos   schedule 17.12.2015TIMEFRAME
- некоторая константа. Обоснование заключается в том, что я хочу пропустить событие, если оно наступит в пределах заданного периода времени после предыдущего события, которое не было пропущено. - person Roman Konoval   schedule 17.12.2015