クエリの構文順序(書き方)は必ずしも実行順序と一致しません。データベースがクエリを処理する際の内部的な手順は、次のようなステップで行われます。
SQLクエリの論理的な実行順序
-
FROM句
- まず、どのテーブルやデータソースからデータを取得するかが決定されます。必要なテーブルが結合されるのもこの段階です。
-
ON句(結合条件)
- 複数のテーブルが結合されている場合、
ON
句を使って結合条件が評価されます。JOIN
が行われる際の条件をここで定義します。
- 複数のテーブルが結合されている場合、
-
JOIN句
- 複数のテーブルがある場合、それらを結合(
JOIN
)します。INNER JOIN
やLEFT JOIN
などの結合がこのステップで処理されます。
- 複数のテーブルがある場合、それらを結合(
-
WHERE句
- 結合が行われた後、
WHERE
句の条件で行のフィルタリングが行われます。指定された条件に一致する行だけが残ります。
- 結合が行われた後、
-
GROUP BY句
- データを集計する際に、どの列を基準にグループ化するかが決まります。このステップでデータがグループ化され、グループごとの集計結果を生成する準備が進められます。
-
HAVING句
- グループ化されたデータに対して、さらに条件を指定してフィルタリングを行います。
HAVING
句は、GROUP BY
によって生成されたグループに適用されます。
- グループ化されたデータに対して、さらに条件を指定してフィルタリングを行います。
-
SELECT句
- このステップで、クエリで指定された列や式が評価されます。つまり、表示するカラムがここで決定されます。データの選択は、この段階で行われます。
-
DISTINCT句
-
SELECT
で取得する行の中から、重複を取り除くためにDISTINCT
が実行されます。
-
-
ORDER BY句
- 最終的な結果セットを指定されたカラムや順序に従って並び替えます。
-
LIMIT句
- 結果セットの行数を制限するための
LIMIT
句が適用され、表示されるデータの行数が決まります。
実行順序のイメージ
たとえば、以下のSQLクエリを考えてみましょう。
SELECT name, COUNT(*)
FROM employees
INNER JOIN departments ON employees.dept_id = departments.id
WHERE employees.salary > 5000
GROUP BY departments.name
HAVING COUNT(*) > 10
ORDER BY name ASC
LIMIT 5;
このクエリの実行順序は次の通りです:
-
FROM:
employees
とdepartments
テーブルを指定。 -
JOIN:
employees.dept_id
とdepartments.id
でINNER JOIN
。 -
WHERE:
employees.salary > 5000
でフィルタリング。 -
GROUP BY: 部門名でグループ化(
departments.name
)。 -
HAVING:
COUNT(*) > 10
の条件を適用。 -
SELECT:
name
とCOUNT(*)
を選択。 -
ORDER BY:
name
で昇順にソート。 - LIMIT: 結果を上位5行に制限。
まとめ
SQLクエリは、SELECT
文を記述する順番とは異なる順序で処理されます。まずデータの取得や結合を行い、その後フィルタリングやグループ化が行われ、最後に結果を選択してソート・制限する流れです。