my opinion is my own

PostgreSQLのSQLの処理順序

処理順序

  1. WITH内のSELECT
  2. FROM
  3. WHERE
  4. GROUP BY
  5. HAVING
  6. SELECT
    • 列に対する関数やDISTINTなど
  7. UNION、INTERSECT、EXCEPT
  8. ORDER BY
  9. LIMIT

マニュアル

SELECT https://www.postgresql.jp/document/14/html/sql-select.html

SELECTは0個以上のテーブルから行を返します。 SELECTの一般的な処理は以下の通りです。

  1. WITHリスト内のすべての問い合わせが計算されます。 これらは実質的には、FROMリスト内から参照可能な一時テーブルとして提供されます。 NOT MATERIALIZEDが指定された場合を除き、FROM内で2回以上参照されるWITH問い合わせは一度のみ計算されます。 (後述のWITH Clauseを参照してください。)
  2. FROMリストにある全要素が計算されます (FROMリストの要素は実テーブルか仮想テーブルのいずれかです)。 FROMリストに複数の要素が指定された場合、それらはクロス結合されます (後述のFROM Clauseを参照してください)。
  3. WHERE句が指定された場合、条件を満たさない行は全て出力から取り除かれます (後述のWHERE Clauseを参照してください)。
  4. GROUP BY句が指定された場合、および集約関数の呼び出しがある場合は、1つまたは複数の値が条件に合う行ごとにグループに組み合わせて出力され、また集約関数の結果が計算されます。 HAVING句が指定された場合、指定した条件を満たさないグループは取り除かれます (後述のGROUP BY ClauseHAVING Clauseを参照してください)。
  5. 実際には、選択された各行または行グループに対して、SELECTの出力式を使用して計算した結果の行が出力されます (後述のSELECT Listを参照してください)。
  6. SELECT DISTINCTは結果から重複行を取り除きます。 SELECT DISTINCT ONは指定した全ての式に一致する行を取り除きます。 SELECT ALLでは、重複行も含め、全ての候補行を返します(これがデフォルトです。 詳しくは、後述のDISTINCT Clauseを参照してください)。
  7. UNIONINTERSECTEXCEPT演算子を使用すると、複数のSELECT文の出力を1つの結果集合にまとめることができます。 UNION演算子は、両方の結果集合に存在する行と、片方の結果集合に存在する行を全て返します。 INTERSECT演算子は、両方の結果集合に存在する行を返します。 EXCEPT演算子は、最初の結果集合にあり、2番目の結果集合にない行を返します。 ALLが指定されない限り、いずれの場合も、重複する行は取り除かれます。 無意味なDISTINCTという単語を付けて、明示的に重複行を除去することを指定することができます。 SELECT自体はALLがデフォルトですが、この場合はDISTINCTがデフォルトの動作であることに注意してください。 (後述のUNION ClauseINTERSECT ClauseEXCEPT Clauseを参照してください。)
  8. ORDER BY句が指定された場合、返される行は指定した順番でソートされます。 ORDER BYが指定されない場合は、システムが計算過程で見つけた順番で行が返されます (後述のORDER BY Clauseを参照してください)。
  9. LIMIT(またはFETCH FIRST)あるいはOFFSET句が指定された場合、SELECT文は結果行の一部分のみを返します (詳しくは、後述のLIMIT Clauseを参照してください)。
  10. FOR UPDATEFOR NO KEY UPDATEFOR SHAREまたはFOR KEY SHARE句を指定すると、SELECT文は引き続き行われる更新に備えて選択行をロックします (詳しくは、後述のThe Locking Clauseを参照してください)。

余談

PostgreSQL 8.0.4とPostgreSQL 14系だとDistinctの処理順序が異なることに気がついた。なんでなんだろう。

---

関連しているかもしれない記事


#PostgreSQL