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|
それが可能かどうか、そしてその方法を知っている人はいますか?どうもありがとうございました!
編集: aと aの 2 つJOIN
の s で実行できることはわかっていますが、実際には数百万行の場合、非常に非効率的です。ORDER BY
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