言語
日本語
English

Caution

お使いのブラウザはJavaScriptが無効になっております。
当サイトでは検索などの処理にJavaScriptを使用しています。
より快適にご利用頂くため、JavaScriptを有効にしたうえで当サイトを閲覧することをお勧めいたします。

  1. トップページ
  2. SQL辞典
  3. サブクエリ(スカラー・行)

サブクエリ(スカラー・行)

対応: SQL-92(1992)

クエリの中に別のSELECT文を埋め込んだものをサブクエリと呼びます。スカラーサブクエリは必ず1列1行の単一値を返し、行サブクエリは1行複数列を返します。

構文

スカラーサブクエリ: SELECT列・WHERE条件・SET句などに単一値として埋め込みます。

SELECT column_name, (SELECT aggregate_function(...) FROM ...) AS alias
FROM table_name;

WHERE句でスカラーサブクエリを使います。

SELECT column_name
FROM table_name
WHERE column_name = (SELECT single_value FROM ...);

行サブクエリ: 複数列を比較します。

SELECT column_name
FROM table_name
WHERE (col_a, col_b) = (SELECT col_a, col_b FROM ... LIMIT 1);

構文一覧

種類概要
スカラーサブクエリ1列1行の単一値を返すサブクエリです。SELECT列・WHERE・SET句などに使えます。
行サブクエリ1行複数列を返すサブクエリです。行値式と組み合わせて複数列を一度に比較できます。

サンプルコード

以下の『employees』テーブルを例に説明します。

employees name salary department 狡噛慎也 480000 執行官 常守朱 620000 監視官 宜野座伸元 390000 監視官 征陸智己 320000 執行官 4 rows in set

各社員の給与と全社員の平均給与を並べて表示します(スカラーサブクエリ)。

sample_subquery_scalar.sql
SELECT
    name,
    salary,
    (SELECT AVG(salary) FROM employees) AS avg_salary,
    salary - (SELECT AVG(salary) FROM employees) AS diff_from_avg
FROM employees
ORDER BY salary DESC;
+------------+--------+------------+---------------+
| name       | salary | avg_salary | diff_from_avg |
+------------+--------+------------+---------------+
| 常守朱     | 620000 |     452500 |        167500 |
| 狡噛慎也   | 480000 |     452500 |         27500 |
| 宜野座伸元 | 390000 |     452500 |        -62500 |
| 征陸智己   | 320000 |     452500 |       -132500 |
+------------+--------+------------+---------------+
4 rows in set

最も給与が高い社員を取得します。

sample_subquery_scalar.sql
SELECT name, salary
FROM employees
WHERE salary = (SELECT MAX(salary) FROM employees);
+--------+--------+
| name   | salary |
+--------+--------+
| 常守朱 | 620000 |
+--------+--------+
1 row in set

以下は発展的な使い方です。最も給与が高い社員と同じ給与・部署の社員を行サブクエリで検索します。

sample_subquery_scalar.sql
SELECT name, salary, department
FROM employees
WHERE (salary, department) = (
    SELECT salary, department
    FROM employees
    ORDER BY salary DESC
    LIMIT 1
);
+--------+--------+------------+
| name   | salary | department |
+--------+--------+------------+
| 常守朱 | 620000 | 監視官     |
+--------+--------+------------+
1 row in set

データベース別の書き方

スカラーサブクエリの構文は主要なデータベースで共通して使用できます。

SELECT name, salary, (SELECT AVG(salary) FROM employees) AS avg_salary
FROM employees
ORDER BY salary DESC;

行サブクエリで結果を1行に制限する書き方はデータベースごとに異なります。MySQL・PostgreSQL・SQLite は『LIMIT 1』を使用します。

SELECT name, salary, department
FROM employees
WHERE (salary, department) = (
    SELECT salary, department FROM employees ORDER BY salary DESC LIMIT 1
);

Oracle は『FETCH FIRST 1 ROW ONLY』を使用します(12c 以降)。それ以前のバージョンでは『ROWNUM』で制限します。

SELECT name, salary, department
FROM employees
WHERE (salary, department) = (
    SELECT salary, department FROM employees ORDER BY salary DESC
    FETCH FIRST 1 ROW ONLY
);

概要

『スカラーサブクエリ』は結果が必ず1列1行でなければなりません。2行以上を返すと実行時エラーになります。集計関数(MAX・MIN・AVG・COUNT)を使うと自然に1行になるため、スカラーサブクエリと相性が良いです。

スカラーサブクエリはSELECT句・WHERE句・HAVING句・SET句(UPDATE文)など多くの場所で使えます。SELECT句に書くと全行に対して毎回評価されるため、大量データに対しては JOIN や派生テーブルへの書き換えを検討してください。

複数行を返すサブクエリとの比較には『IN / EXISTS』や『ALL / ANY』を使います。外側のクエリを参照するサブクエリは『相関サブクエリ』を参照してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。