PostgreSQLのSQLの処理順序
処理順序
- WITH内のSELECT
- FROM
- WHERE
- GROUP BY
- HAVING
- SELECT
- 列に対する関数やDISTINTなど
- UNION、INTERSECT、EXCEPT
- ORDER BY
- LIMIT
マニュアル
SELECT https://www.postgresql.jp/document/14/html/sql-select.html
SELECT
は0個以上のテーブルから行を返します。SELECT
の一般的な処理は以下の通りです。
WITH
リスト内のすべての問い合わせが計算されます。 これらは実質的には、FROM
リスト内から参照可能な一時テーブルとして提供されます。NOT MATERIALIZED
が指定された場合を除き、FROM
内で2回以上参照されるWITH
問い合わせは一度のみ計算されます。 (後述のWITH Clauseを参照してください。)FROM
リストにある全要素が計算されます (FROM
リストの要素は実テーブルか仮想テーブルのいずれかです)。FROM
リストに複数の要素が指定された場合、それらはクロス結合されます (後述のFROM Clauseを参照してください)。WHERE
句が指定された場合、条件を満たさない行は全て出力から取り除かれます (後述のWHERE Clauseを参照してください)。GROUP BY
句が指定された場合、および集約関数の呼び出しがある場合は、1つまたは複数の値が条件に合う行ごとにグループに組み合わせて出力され、また集約関数の結果が計算されます。HAVING
句が指定された場合、指定した条件を満たさないグループは取り除かれます (後述のGROUP BY ClauseとHAVING Clauseを参照してください)。- 実際には、選択された各行または行グループに対して、
SELECT
の出力式を使用して計算した結果の行が出力されます (後述のSELECT Listを参照してください)。SELECT DISTINCT
は結果から重複行を取り除きます。SELECT DISTINCT ON
は指定した全ての式に一致する行を取り除きます。SELECT ALL
では、重複行も含め、全ての候補行を返します(これがデフォルトです。 詳しくは、後述のDISTINCT Clauseを参照してください)。UNION
、INTERSECT
、EXCEPT
演算子を使用すると、複数のSELECT
文の出力を1つの結果集合にまとめることができます。UNION
演算子は、両方の結果集合に存在する行と、片方の結果集合に存在する行を全て返します。INTERSECT
演算子は、両方の結果集合に存在する行を返します。EXCEPT
演算子は、最初の結果集合にあり、2番目の結果集合にない行を返します。ALL
が指定されない限り、いずれの場合も、重複する行は取り除かれます。 無意味なDISTINCT
という単語を付けて、明示的に重複行を除去することを指定することができます。SELECT
自体はALL
がデフォルトですが、この場合はDISTINCT
がデフォルトの動作であることに注意してください。 (後述のUNION Clause、INTERSECT Clause、EXCEPT Clauseを参照してください。)ORDER BY
句が指定された場合、返される行は指定した順番でソートされます。ORDER BY
が指定されない場合は、システムが計算過程で見つけた順番で行が返されます (後述のORDER BY Clauseを参照してください)。LIMIT
(またはFETCH FIRST
)あるいはOFFSET
句が指定された場合、SELECT
文は結果行の一部分のみを返します (詳しくは、後述のLIMIT Clauseを参照してください)。FOR UPDATE
、FOR NO KEY UPDATE
、FOR SHARE
またはFOR KEY SHARE
句を指定すると、SELECT
文は引き続き行われる更新に備えて選択行をロックします (詳しくは、後述のThe Locking Clauseを参照してください)。
余談
PostgreSQL 8.0.4とPostgreSQL 14系だとDistinctの処理順序が異なることに気がついた。なんでなんだろう。
関連しているかもしれない記事
- Aurora PostgreSQLでPostGIS(位置情報)を使用する
- PostgreSQL のテーブルをリネームした場合、統計情報やインデックス、バッファキャッシュはどうなるか?
- Aurora PostgreSQLのDB監査方式(Database Activity Streams or pgaudit?)
- PostgreSQLでソートをメモリでは無く敢えてディスクで発生させる方法
- OracleとPostgreSQLの統計情報取得のサンプリング数の違いについて