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

GROUPBYでTOPのようなものを使用します

    DISTINCT ONを使用すると、グループごとに最も長い名前の乗客を簡単に取得できます。 。

    しかし、それ(または他の簡単な方法)を単一のSELECTで元のクエリと組み合わせる方法はわかりません。 。 2つの別々のサブクエリに参加することをお勧めします:

    SELECT *
    FROM  (  -- your original query
       SELECT orig
            , count(*) AS flight_cnt
            , count(distinct passenger) AS pass_cnt
            , percentile_cont(0.5) WITHIN GROUP (ORDER BY bags) AS bag_cnt_med
       FROM   table1
       GROUP  BY orig
       ) org_query
    JOIN  (  -- my addition
       SELECT DISTINCT ON (orig) orig, passenger AS pass_max_len_name
       FROM   table1
       ORDER  BY orig, length(passenger) DESC NULLS LAST
       ) pas USING (orig);
    

    USING join句では、便利なことにorigのインスタンスを1つだけ出力します。 、したがって、SELECT *を使用するだけです。 外側のSELECT

    passengerの場合 NULLにすることもできますが、NULLS LASTを追加することが重要です。 :

    同じグループ内の同じ最大長の複数の乗客名から、任意の選択を取得します -ORDER BYに式を追加しない限り タイブレーカーとして。上にリンクされた回答の詳細な説明。

    パフォーマンス?

    通常、特にシーケンシャルスキャンでは、シングルスキャンの方が優れています。

    上記のクエリは2つを使用します スキャン(多分インデックス/インデックスのみのスキャン)。ただし、テーブルが大きすぎてキャッシュに収まらない場合を除いて、2回目のスキャンは比較的安価です(ほとんどの場合)。 Lukasは、シングルのみの代替クエリを提案しました SELECT 追加:

    , (ARRAY_AGG (passenger ORDER BY LENGTH (passenger) DESC))[1]  -- I'd add NULLS LAST
    

    アイデアは賢いですが、前回テストした 、array_agg ORDER BYを使用 あまりうまく機能しませんでした。 (グループごとのORDER BYのオーバーヘッド かなりの量であり、配列の処理にも費用がかかります。)

    同じアプローチは、カスタム集計関数 first()を使用すると安価になる可能性があります こちらのPostgresWikiで指示されているように 。または、 Cで記述されたバージョンで、PGXNで入手可能 を使用すると、さらに高速になります。 。配列処理の余分なコストを排除しますが、それでもグループごとのORDER BYが必要です 。 高速になる可能性があります 少数のグループのみ。次に、次を追加します:

     , first(passenger ORDER BY length(passenger) DESC NULLS LAST)
    

    ゴードン および Lukas ウィンドウ関数first_value() 。ウィンドウ関数はに適用されます 集計関数。同じSELECTで使用するには 、passengerを集計する必要があります どういうわけか 最初-キャッチ22。ゴードンはサブクエリでこれを解決します-標準のPostgresで優れたパフォーマンスを発揮するもう1つの候補です。

    first() サブクエリなしでも同じことを行い、より単純で少し高速になるはずです。ただし、それでも別のDISTINCT ONよりも高速になることはありません。 ほとんどの場合、グループあたりの行数は少なくなります。グループごとに多数の行がある場合、通常、再帰CTE手法の方が高速です。関連するすべての一意のorigを保持する別のテーブルがある場合は、さらに高速な手法があります。 値。詳細:

    最善の解決策は、さまざまな要因によって異なります。プリンの証拠は食べることです。パフォーマンスを最適化するには、セットアップでテストする必要があります。上記のクエリは最速の1つです。



    1. MAMPPro3を使用してmysqlデータベースをDropboxと同期します

    2. OracleでSQLチューニングを行う方法

    3. SQL Serverで「smalldatetime」を「datetime」に変換する(T-SQLの例)

    4. AND / OR Search Django-Postgres Appを実行するための効率的な方法は何ですか?