我正在尝试找到与 PostgreSQL 查询中的 WINDOW 函数中的 PARTITION BY 子句中的当前行进行比较的方法。
想象一下,我在以下 5 个元素的查询中有一个短列表(在实际情况下,我有数千甚至数百万行)。我试图为每一行获取下一个不同元素(事件列)的 id,以及前一个不同元素的 id。
WITH events AS(
SELECT 1 as id, 12 as event, '2014-03-19 08:00:00'::timestamp as date
UNION SELECT 2 as id, 12 as event, '2014-03-19 08:30:00'::timestamp as date
UNION SELECT 3 as id, 13 as event, '2014-03-19 09:00:00'::timestamp as date
UNION SELECT 4 as id, 13 as event, '2014-03-19 09:30:00'::timestamp as date
UNION SELECT 5 as id, 12 as event, '2014-03-19 10:00:00'::timestamp as date
)
SELECT lag(id) over w as previous_different, event
, lead(id) over w as next_different
FROM events ev
WINDOW w AS (PARTITION BY event!=ev.event ORDER BY date ASC);
我知道比较event!=ev.event
是不正确的,但这就是我想要达到的目的。
我得到的结果是(就像我删除 PARTITION BY 子句一样):
|12|2
1|12|3
2|13|4
3|13|5
4|12|
我想得到的结果是:
|12|3
|12|3
2|13|5
2|13|5
4|12|
任何人都知道这是否可能以及如何?非常感谢!
编辑:我知道我可以用两个JOIN
s、 aORDER BY
和 a来做到这一点DISTINCT ON
,但在数百万行的实际情况下,效率非常低:
WITH events AS(
SELECT 1 as id, 12 as event, '2014-03-19 08:00:00'::timestamp as date
UNION SELECT 2 as id, 12 as event, '2014-03-19 08:30:00'::timestamp as date
UNION SELECT 3 as id, 13 as event, '2014-03-19 09:00:00'::timestamp as date
UNION SELECT 4 as id, 13 as event, '2014-03-19 09:30:00'::timestamp as date
UNION SELECT 5 as id, 12 as event, '2014-03-19 10:00:00'::timestamp as date
)
SELECT DISTINCT ON (e.id, e.date) e1.id, e.event, e2.id
FROM events e
LEFT JOIN events e1 ON (e1.date<=e.date AND e1.id!=e.id AND e1.event!=e.event)
LEFT JOIN events e2 ON (e2.date>=e.date AND e2.id!=e.id AND e2.event!=e.event)
ORDER BY e.date ASC, e.id ASC, e1.date DESC, e1.id DESC, e2.date ASC, e2.id ASC