1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【完走賞めざす!】データベースとSQLのススメAdvent Calendar 2023

Day 9

サブクエリ(副問い合わせ)基礎 〜複数行サブクエリ編〜

Last updated at Posted at 2023-12-08

はじめに

サブクエリとは簡単にいうとSQL文の中にSQL文を書くことです。
サブクエリは複雑な問い合わせをしたい時に役立ちます。

サブクエリの使い方には大まかに以下三つが挙げられます。

  • スカラー・サブクエリ
  • 複数行サブクエリ
  • 相関サブクエリ

シリーズものとして、本記事では複数行サブクエリについて記述します。
「はじめに」は同シリーズすべて同じ内容です。一読された方は読み飛ばしてください。

備考

この記事ではMySQLを使った書き方をします。

サブクエリの使い道

サブクエリの用途は色々ありますが、主な用途は「柔軟なSQLクエリを作成するため」です。
サブクエリの中にサブクエリを書くこともできネストを作成できます。また、記述できる場所はSELECT句でもGROUP BY句でもHAVING句でもどこでも書くことができ、非常に柔軟性に富んでいます。

しかし、あまりにもネストが深くなると、パフォーマンスに影響が出る他、読みづらいスパゲッティクエリとなってしまうため、注意が必要です。

複数行サブクエリ

たとえば、会社の上司から、「過去1か月間で、なにかしら注文してくれた、すべての顧客を検索したい」と命じられたとき。
以下のようなクエリになります。

SELECT
    *
FROM
    customers -- 顧客テーブル
WHERE
    -- なにかしら注文してくれた顧客を絞り込む
    customer_id IN(
        SELECT DISTINCT
            customer_id
        FROM
            orders
        WHERE
            order_date >= DATE_ADD(now(), INTERVAL -1 MONTH) -- 注文日が1ヶ月前からの注文を絞り込む
    )
;

この例では、サブクエリは、注文日が過去1か月以内であるすべての顧客IDを「orders」テーブルから取得します。次に、外側のクエリは、顧客IDがサブクエリによって返されたIDの1つと一致する、すべての列を「customers」テーブルから取得します。

まとめ

サブクエリの複数行サブクエリについて解説しました。

おまけ

スカラーサブクエリ、複数行サブクエリ、相関サブクエリに関する詳細をまとめます。

種類 説明 主に使う構文 使用例
スカラー・サブクエリ 単一の値(1行1列)を返します。SELECT文の中で単一の値を返す必要がある場所で使われます。 AVG , 演算子(>,<,=) SELECT * FROM テーブル WHERE 列 = (SELECT AVG(列) FROM テーブル WHERE 条件);
複数行サブクエリ 一つ以上の行を返すことができます。 IN,ANY,ALL,演算子(>,<,=) SELECT * FROM テーブル WHERE 列 IN (SELECT 列 FROM テーブル WHERE 条件);
相関サブクエリ 外側のクエリと「相関」している内側のクエリです。外側のクエリの各行に対して内側のクエリが実行され、外側の列を参照できます。 IN, EXISTS ,演算子(>,<,=) SELECT * FROM テーブルA WHERE EXISTS (SELECT * FROM テーブルB WHERE テーブルB.列 = テーブルA.列);

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?