SQL・クエリ

サブクエリ・CTE さぶくえり・しーてぃーいー

サブクエリCTEWITH句共通テーブル式再帰クエリSQL
サブクエリ・CTEについて教えて

簡単に言うとこんな感じ!

サブクエリは「SQLの中にSQLを入れ子にする」仕組み、CTEは「名前付きの一時的な問い合わせ結果を使い回す」仕組みだよ!「平均より高い商品を探す」とか「月次集計を使って前月比を出す」みたいな複雑な問い合わせを、読みやすく段階的に書けるのが強みなんだ!


サブクエリ・CTEとは

サブクエリ(Subquery)とは、SQLの中に別のSELECT文を埋め込む構文です。外側のクエリ(メインクエリ)が結果を参照する「内側のクエリ」です。WHERE句・FROM句・SELECT句など様々な場所に記述できます。「全商品の平均価格より高い商品を取得する」のように、「まず内側を実行してその結果を外側で使う」2段階の処理を1つのSQLで表現できます。

CTE(Common Table Expression:共通テーブル式)は、WITH句を使ってサブクエリに名前を付け、後続のクエリで繰り返し参照できるようにした構文です。SQL:1999で標準化されました。CTEはサブクエリと比べて可読性が高く、デバッグが容易で、同じ結果セットを複数回参照できる利点があります。

CTEの特別な応用として再帰CTE(Recursive CTE)があります。WITH RECURSIVEを使うことで、組織の上下関係・カテゴリの階層・ツリー構造などの再帰的なデータを1つのSQLで辿ることができます。これはサブクエリでは実現が難しい複雑な処理です。


サブクエリの種類

種類場所特徴
スカラーサブクエリSELECT句・WHERE句1行1列の値を返すAVG価格をSELECTで使う
インラインビューFROM句テーブルのように扱える集計済み結果を FROM で使う
相関サブクエリWHERE句外側のクエリの値を参照各部門の最高給与を求める
EXISTS/IN サブクエリWHERE句存在チェック・リスト絞り込み注文のある顧客だけを取得
サブクエリ vs CTE の書き方比較 サブクエリ(ネスト形式) SELECT name, price FROM products WHERE price > ( -- サブクエリ(内側) SELECT AVG(price) FROM products ); CTE(WITH句) WITH avg_price AS ( -- 名前付きサブクエリ SELECT AVG(price) AS avg ) SELECT name, price FROM products, avg_price WHERE price > avg_price.avg; 再帰CTE(WITH RECURSIVE) — 組織の上下関係を全展開 WITH RECURSIVE org_tree AS ( SELECT id, name, parent_id, 1 AS depth FROM employees WHERE parent_id IS NULL -- アンカー(起点) UNION ALL SELECT e.id, e.name, e.parent_id, t.depth + 1 FROM employees e JOIN org_tree t ON e.parent_id = t.id -- 再帰 )

歴史と背景

  • 1974年:IBM SEQUELでサブクエリの概念が実装
  • 1987年:SQL-87でサブクエリが標準化
  • 1999年:SQL:1999でCTE(WITH句)と再帰CTEが標準化
  • 2000年代:PostgreSQL・Oracle・SQL Serverが相次いでCTE対応
  • 2018年:MySQL 8.0でCTEに対応(長らく未対応だった)
  • 現在:CTEはSQL可読性向上のベストプラクティスとして広く推奨される

サブクエリ vs CTE の使い分け

観点サブクエリCTE
可読性ネストが深いと読みにくい名前付きで構造が明確
再利用同じ結果を複数回使えない複数回参照可能
デバッグWITH部分だけ実行できないWITH部分だけ実行可能
再帰不可可能(RECURSIVE)
パフォーマンスDBにより最適化が異なる多くのDBでサブクエリと同等

関連する規格・RFC

規格・RFC番号内容
ISO/IEC 9075:1999CTE(WITH句)と再帰CTEの標準化
ISO/IEC 9075:2003CTEの挙動の詳細規定

関連用語