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

LIMIT / OFFSETを使用してクエリを実行し、行の総数も取得します

    はい。 シンプルなウィンドウ関数を使用する場合:

    SELECT *, count(*) OVER() AS full_count
    FROM   tbl
    WHERE  /* whatever */
    ORDER  BY col1
    OFFSET ?
    LIMIT  ?

    コストは総数がない場合よりも大幅に高くなりますが、通常は2つの個別のクエリよりも安価であることに注意してください。 Postgresは実際にすべての行をカウントする必要があります いずれの場合も、対象となる行の総数に応じてコストがかかります。詳細:

    • LIMITが適用される前に結果カウントを取得するための最良の方法

    ただし 、ダニが指摘したように、OFFSET 少なくとも基本クエリから返される行数と同じ数である場合、行は返されません。したがって、full_countも取得しません 。

    それが受け入れられない場合は、常にフルカウントを返すための回避策が考えられます。 CTEとOUTER JOINを使用します :

    WITH cte AS (
       SELECT *
       FROM   tbl
       WHERE  /* whatever */
       )
    SELECT *
    FROM  (
       TABLE  cte
       ORDER  BY col1
       LIMIT  ?
       OFFSET ?
       ) sub
    RIGHT  JOIN (SELECT count(*) FROM cte) c(full_count) ON true;
    

    full_countでNULL値の1行を取得します OFFSETの場合に追加 大きすぎます。それ以外の場合は、最初のクエリのようにすべての行に追加されます。

    すべてNULL値の行が有効な結果である可能性がある場合は、offset >= full_countを確認する必要があります。 空の行の原点を明確にします。

    これでも、基本クエリは1回だけ実行されます。ただし、クエリにオーバーヘッドが追加され、カウントの基本クエリを繰り返すよりも少ない場合にのみ支払いが行われます。

    最終的な並べ替え順序をサポートするインデックスが利用できる場合は、ORDER BYを含めるとよい場合があります。 CTEで(冗長に)。



    1. Rails:PG ::UndefinedTable:エラー:リレーション...が存在しません

    2. カウントにギャップを残してプライマリを自動インクリメント

    3. ダウンロード用の安全なファイル

    4. Oracle PL / SQL開発者で日付付きの時間部分を表示するための設定は何ですか?