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

PostgreSQLの1行のウィンドウ関数の最初と最後の値

    質問は古いですが、この解決策はこれまでに投稿されたものよりも簡単で高速です:

    SELECT b.machine_id
         , batch
         , timestamp_sta
         , timestamp_stp
         , min(timestamp_sta) OVER w AS batch_start
         , max(timestamp_stp) OVER w AS batch_end
    FROM   db_data.sta_stp a
    JOIN   db_data.ll_lu   b ON a.ll_lu_id = b.id
    WINDOW w AS (PARTITION BY batch, b.machine_id) -- No ORDER BY !
    ORDER  BY timestamp_sta, batch, machine_id; -- why this ORDER BY?
    

    ORDER BYを追加した場合 ウィンドウフレーム定義に、より大きなORDER BYを持つ次の各行 式のフレーム開始は遅くなります。どちらもmin() また、first_value() その後、パーティション全体の「最初の」タイムスタンプを返すことができます。 ORDER BYなし 同じパーティションのすべての行はピアです 希望する結果が得られます。

    追加したORDER BY 動作 (ウィンドウフレーム定義の1つではなく、外側の1つ)が、意味がないようで、クエリのコストが高くなります。おそらくORDER BYを使用する必要があります 追加のソートコストを回避するためにウィンドウフレーム定義に同意する句:

    ... 
    ORDER BY batch, b.machine_id, timestamp_sta, timestamp_stp;
    

    DISTINCTの必要性がわかりません このクエリで。実際に必要な場合は、追加するだけです。またはDISTINCT ON () 。ただし、ORDER BY 条項はさらに関連性が高くなります。参照:

    同じ行から他の列が必要な場合(タイムスタンプで並べ替える場合)、FIRST_VALUE()を使用してください。 およびLAST_VALUE() 行く方法かもしれません。おそらく、これをウィンドウフレーム定義に追加する必要があります次に

    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
    

    参照:



    1. Tsrange-2つの範囲の差を計算する

    2. ORACLE:LEFTJOINを使用するとマテリアライズドビューが機能しない

    3. 特定のファイルの場所からmysqlデータベースをインポートするためのスクリプト

    4. MySQLの情報スキーマのクエリ:なぜですか?どのように?