-
COALESCE
を使用する @Justinが提供したように。 -
first_value()
を使用 /last_value()
必要ORDER BY
を追加するには ウィンドウ定義または順序の句が未定義 。ダミーテーブルを作成した直後に行が順番に並んでいるため、この例では幸運に恵まれました。
ORDER BY
を追加したら 、デフォルトのウィンドウフレームは現在の行で終了します 、およびlast_value()
を特殊なケースにする必要があります 呼び出す-または、最初の例で示したように、ウィンドウフレームの並べ替え順序を元に戻します。 -
ウィンドウ定義を複数回再利用する場合は、明示的な
WINDOW
句は構文を大幅に簡素化します:
SELECT ring, part, ARRAY[
coalesce(
lag(part) OVER w
,first_value(part) OVER (PARTITION BY ring ORDER BY part DESC))
,part
,coalesce(
lead(part) OVER w
,first_value(part) OVER w)
] AS neighbours
FROM rp
WINDOW w AS (PARTITION BY ring ORDER BY part);
さらに良い 、同じウィンドウ定義を再利用して、Postgresが1回のスキャンですべての値を計算できるようにします。これを機能させるには、カスタムウィンドウフレームを定義する必要があります :
SELECT ring, part, ARRAY[
coalesce(
lag(part) OVER w
,last_value(part) OVER w)
,part
,coalesce(
lead(part) OVER w
,first_value(part) OVER w)
] AS neighbours
FROM rp
WINDOW w AS (PARTITION BY ring
ORDER BY part
RANGE BETWEEN UNBOUNDED PRECEDING
AND UNBOUNDED FOLLOWING)
ORDER BY 1,2;
各ウィンドウ関数呼び出しのフレーム定義を調整することもできます:
SELECT ring, part, ARRAY[
coalesce(
lag(part) OVER w
,last_value(part) OVER (w RANGE BETWEEN CURRENT ROW
AND UNBOUNDED FOLLOWING))
,part
,coalesce(
lead(part) OVER w
,first_value(part) OVER w)
] AS neighbours
FROM rp
WINDOW w AS (PARTITION BY ring ORDER BY part)
ORDER BY 1,2;
パーツが多いリングの方が速いかもしれません。テストする必要があります。
SQLフィドル 改善されたテストケースで3つすべてを示します。クエリプランを検討してください。
ウィンドウフレーム定義の詳細:
- マニュアル内。
- PostgreSQLウィンドウ関数:比較によるパーティション
- 最大日と最小日、および行ごとに関連付けられたIDを使用したPostgreSQLクエリ