sql >> データベース >  >> RDS >> PostgreSQL

ウィンドウ関数でリングデータ構造を使用する方法

    • 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クエリ


    1. Oracle10gタイムゾーンの混乱

    2. PHPとPostgres:エラーをキャッチしますか?

    3. SQLServer2017でテーブルを作成する

    4. SQLite IN