ぽかぽかコード日和

とっても暑い夏の日にプログラミングはじめました☀️

【SQL】副問い合わせ(サブクエリ)

副問い合わせとは

副問い合わせとは、
SQL文の内部に別のSELECT文を記述すること。

  • 1つのSQL文で2つ以上の処理ができ、DBMSに対して柔軟な指示ができる仕組み。
  • 副問い合わせは、()で括って記述する。

  • WHERE・SELECT・FROM・HAVING句、INSERT/UPDATE/DELETE文などさまざまな場所で使える。

  • 内側のSELECT文(副問い合わせ)」が先に実行され、
    その結果を使って「外側のSQL文(主問い合わせ)」が実行される。

  • 副問い合わせの中でさらに副問い合わせを使える(ネスト)が、SQLが複雑になりやすい。

副問い合わせの種類

内側のSELECT文の結果の構造や依存関係によって、3つに分けられる。

1.単一行副問い合わせ(スカラーサブクエリ)

  • 「1つの値(1行1列)」だけを返す。
  • 比較演算子で直接比較ができる。
SELECT  *
 FROM  orders
 WHERE  price = (SELECT MAX(price)
           FROM   orders
           );

☀︎ordersテーブルの最も高い価格のすべての列を取得できる。

2.複数行副問い合わせ

IN / NOT IN(条件に当てはまるものを抽出)
SELECT *
FROM customers
WHERE id IN (SELECT customer_id 
        FROM orders
        WHERE price >= 5000
        );

☀︎5,000円以上の注文履歴がある顧客の情報一覧を取得できる。
- NOT INでは「5,000円以上の注文履歴がない顧客」と否定形となる。

3.相関副問い合わせ

  • 外側のテーブルの値を1行ずつ副問い合わせに渡して実行し判定する
    そのため、各行ごとに異なる結果となり条件に当てはまった行のみ返す
EXISTS(存在のチェック)
  • 外側のテーブルの各行ごとに副問い合わせを実行し、TRUEかFALSEの判断を繰り返す。
  • そのデータが副問い合わせの中に存在すると「真」、存在しないと「偽」となる。
  • NOT EXESTSは真と偽が反対になる。
SELECT *
FROM customers
WHERE EXISTS (
         SELECT customer_id
         FROM orders
         WHERE orders.customer_id = customers.id
         );

☀︎ordersテーブルに注文履歴がある顧客の情報一覧を取得できる

副問い合わせとJOIN句の使い分け

複数行副問い合わせの「5,000円以上の注文履歴がある顧客の情報一覧」を、
JOINを使って書くこともできる。

SELECT DISTINCT customers.*
FROM customers
JOIN orders ON orders.customer_id  = customers.id
WHERE orders.price >= 5000;
  • 副問い合わせは

    • 条件付きの絞り込みや複雑な条件・集計結果に使うと便利。
    • FROM句で使うと、一時的なテーブルのように扱える。
    • 大量データのときは処理が遅くなりやすい。
  • JOIN句は

    • 複数テーブルのカラムを同時に取得するときや、関連データをまとめて処理したいときに使う。
    • 複数のテーブルを組み合わせた集計や分析に便利
    • インデックスが貼られている場合、大量データでも高速に処理ができる。

参考にしたサイト