第10回: サブクエリとCTEの基本 — 複雑なSQLを「読める」形に分解する

章: 第2章: 実務クエリ基礎

ネストが深いSQLを引き継いだとき、何から読めばいいかわかりますか?

サブクエリを多重にネストしたSQLは、どこが何を返しているのか追いにくく、バグの原因も特定しづらくなります。3段ネストのサブクエリは、書いた本人でも翌週には読めないことがあります。

CTE(Common Table Expression)を使うと、複雑なクエリを意図が見える形に分解できます。 可読性が上がれば、チームレビューも保守もスムーズになります。

サブクエリ vs CTE ——どちらを選ぶべきか

どちらも「クエリの中でクエリを使う」点は同じですが、構造の明確さが大きく異なります。まずCTEで書いてみて、クエリが一度しか使われない場合はサブクエリに戻す、という判断が実務では安全です。

サブクエリ vs CTE の比較

観点 サブクエリ CTE(WITH句)
可読性 ネストが深いと読みにくい 名前をつけて分割できる
再利用 同じ式を複数回書く必要あり 同一クエリ内で複数回参照できる
デバッグ 部分的に実行しにくい CTEを単独でSELECTして確認できる
MySQL対応 全バージョン対応 MySQL 8.0以降で利用可能

チェックポイント: CTE は WITH 名前 AS (クエリ) SELECT ... という構文で書きます。CTEを単独で SELECT * FROM 名前 のように実行して結果を確認できるため、デバッグが格段にやりやすくなります。複雑なクエリを書くときはまずCTEで段階的に組み立て、最終的にまとめる戦略が有効です。

実際のコードのサンプル


WITH recent_posts AS (
  SELECT *
  FROM posts
  WHERE created_at >= NOW() - INTERVAL 7 DAY
)
SELECT user_id, COUNT(*) AS cnt
FROM recent_posts
GROUP BY user_id;

まとめ & 次のステップ

  • サブクエリはネストが深くなると可読性が急激に落ちる
  • CTE(WITH句)はクエリに名前をつけて分割でき、デバッグや再利用に優れる
  • CTEは MySQL 8.0以降で利用可能。バージョンを確認してから使う
  • 複雑な条件は「まずCTEで段階的に組み立てる」アプローチが保守性を高める

次回は 「インデックスの基本戦略」 を学びます。クエリがなぜ遅いのかを正しく診断し、適切なインデックスで根本から解決する方法を確認します。

Related Articles