サブクエリは、SQLにおける機能で、1つのクエリ内で他のクエリを実行する仕組みを提供します。
サブクエリは「ネストされたクエリ」とも呼ばれ、主にデータの一部を他のクエリの結果に基づいて取得したい場合に使用されます。
サブクエリは、SELECT
、FROM
、WHERE
、HAVING
、JOIN
などさまざまな場所で使用できます。
サブクエリの主な種類
- スカラーサブクエリ
1つの値を返すサブクエリ。通常、WHERE
やSELECT
で使用されます。 - 行サブクエリ
複数の値を返し、複数の列にマッチする場合に使用されます。 - テーブルサブクエリ
完全なテーブル(複数の行と列)を返します。
サブクエリの使用方法
WHERE
句でのサブクエリの使用
サブクエリは通常、WHERE
句で使用されます。
例として、従業員テーブルから特定の部署に所属する従業員を検索する場合を考えます。
SELECT name
FROM employees
WHERE department_id = (
SELECT department_id
FROM departments
WHERE department_name = '営業'
);
このクエリでは、サブクエリがdepartments
テーブルから「営業」部署のdepartment_id
を取得し、その値に基づいてemployees
テーブルから従業員をフィルタリングしています。
FROM
句でのサブクエリの使用
サブクエリをFROM
句で使用すると、一時的なテーブルとして扱うことができます。
この場合、サブクエリが1つのテーブルとして振る舞います。
SELECT department_name, avg_salary
FROM (
SELECT department_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id
) AS avg_dept_salary
JOIN departments ON avg_dept_salary.department_id = departments.department_id;
このクエリでは、従業員ごとの給与を集計したサブクエリをFROM
句で使用し、その結果をdepartments
テーブルと結合しています。
SELECT
句でのサブクエリの使用
SELECT
句でサブクエリを使用すると、特定の列に対してサブクエリの結果を挿入できます。
SELECT name,
(SELECT department_name
FROM departments
WHERE departments.department_id = employees.department_id) AS department_name
FROM employees;
この例では、employees
テーブルの従業員名と、各従業員が所属する部署名をサブクエリを使って取得しています。
EXISTS
を使用したサブクエリ
EXISTS
を使用するサブクエリは、サブクエリが1つ以上の結果を返すかどうかをチェックします。
例えば、ある部署に従業員がいるかどうかを確認したい場合には次のように記述します。
SELECT department_name
FROM departments d
WHERE EXISTS (
SELECT 1
FROM employees e
WHERE e.department_id = d.department_id
);
このクエリは、departments
テーブルから従業員が存在する部署名を返します。
EXISTS
はサブクエリが結果を返すかどうかだけを確認するため、SELECT
句の内容は重要ではありません(この例ではSELECT 1
が使われています)。
サブクエリの注意点
- パフォーマンスの問題
サブクエリは便利ですが、場合によってはパフォーマンスに影響を与えることがあります。
特に大規模なデータセットでは、インデックスの利用や結合(JOIN)を使って効率的に処理することを検討すべきです。 - 読みやすさ
サブクエリを多用すると、クエリが複雑になり読みづらくなることがあります。
必要に応じて、ビューやCTE(共通テーブル式)を使用して可読性を向上させると良いです。
可読性を上げるために便利な、WITH句の使い方を別の記事でまとめてあります!
まとめ
サブクエリは、1つのクエリ内で別のクエリを実行する便利な方法であり、特定の条件に基づいて柔軟なデータの抽出が可能です。主にWHERE
、FROM
、SELECT
句で使用され、EXISTS
と組み合わせて存在確認を行うこともできます。サブクエリを効果的に使うためには、パフォーマンスへの配慮やクエリの読みやすさを意識することが重要です。