サブクエリ・CTEとは(全体像)
サブクエリは、SELECT文の中に、もう1つのSELECT文を入れたもの。内側でまず答え(値や行の集まり)を出して、それを外側の問い合わせで使うよー。
CTEは、WITH句を使って、一時的な結果に名前をつけて先に用意しておくしくみ。長くて入り組んだ問い合わせを、読みやすく整理できるのー。
身近にたとえると、下書きメモに名前をつけておく感じ。「まずこの集計を『メモA』として用意して、本番ではメモAを使う」とすると、見通しがよくなるよー。
押さえるのは、サブクエリの種類と、再帰CTEで階層をたどれることだよー。
詳しく:サブクエリの種類と再帰CTEだけ覚えれば戦える
ここが記事の心臓部。まずサブクエリの種類を見ていこーね。
サブクエリの主な種類
| 種類 | 内容 |
|---|---|
| スカラサブクエリ | 単一の値を返す(列の値として使う) |
| IN/EXISTS | 存在チェック(あるかどうかを調べる) |
| 相関サブクエリ | 外側の問い合わせの列を参照(行ごとに計算・性能注意) |
ここで一番のひっかけが「INとEXISTSは性能がいつも同じ」という誤解。多くの場合EXISTSのほうが性能がよい(空欄=NULLの扱いにも違いがある)ので、同じだと決めつけないよー。
次に、CTEと再帰CTE。
CTEと再帰CTE
| 種類 | 内容 |
|---|---|
| CTE(WITH句) | 一時的な結果に名前をつけて読みやすくする |
| 再帰CTE(WITH RECURSIVE) | 自分を呼び出して階層をたどる(組織ツリーなど) |
再帰CTEは「WITH RECURSIVE」と書いて、組織ツリー(上司→部下→そのまた部下…)のような階層を、上から順にたどって展開できるのがポイントだよー。
ここで2つめのひっかけが「MySQLはCTEに対応していない」という古い思い込み。MySQLは8.0からCTEに対応しているので、決めつけないでねー。
わかりやすく言い換えると
要するに、下書きメモでイメージするとラクだよー。
①サブクエリ … 問い合わせの中の問い合わせ(内側で答えを出して外側で使う)
②CTE … WITHで一時的な結果に名前をつけて読みやすくする(下書きメモ)
③再帰CTE … WITH RECURSIVEで組織ツリーなどの階層をたどる
つまり、「サブクエリは問い合わせの中の問い合わせ」「再帰CTEで階層をたどる」、この2点が試験の急所なのー。
試験のツボ
🔴 一番出る:サブクエリの種類
①サブクエリは問い合わせ(SELECT)の中の問い合わせ
②スカラ・IN/EXISTS・相関の3種(相関サブクエリは行ごとに計算され性能に注意)
🔴 次に出る:CTEと再帰CTE
①CTE(WITH句)は一時的な結果に名前をつけて読みやすくする
②再帰CTE(WITH RECURSIVE)は組織ツリーなどの階層をたどれる
🟡 押さえると安定:IN/EXISTSとMySQL対応
①多くの場合EXISTSのほうが性能がよい(INと同じとは限らない)
②MySQLは8.0からCTEに対応している
よくある間違い
①「INとEXISTSは性能がいつも同じである」→ ✗ 多くの場合EXISTSのほうが性能がよい。NULLの扱いにも違いがある。
②「MySQLはCTEに対応していない」→ ✗ MySQLは8.0から対応している。古いバージョンの思い込み。
③「サブクエリはSELECTの外にしか書けない」→ ✗ サブクエリはSELECT文の中に入れる「問い合わせの中の問い合わせ」。
試験での出題パターン
実際の問題でたしかめてみよう。
オリジナル問題1(サブクエリとは)
サブクエリに関する次の記述のうち、正しいものはどれか。
- サブクエリは画面に小さな窓をいくつも表示するための機能のことだとされているものである
- サブクエリは問い合わせ(SELECT)の中に入れた、もう1つの問い合わせのことである
- サブクエリはデータを必ず3つに分割する命令のことだとされているものである
- サブクエリは音を鳴らして知らせるための設定のことだとされているものである
解答は 2 だよー。
サブクエリは、問い合わせ(SELECT)の中に入れた、もう1つの問い合わせなのー。内側でまず答えを出して、それを外側で使う感じだよー。
選択肢1の「小さな窓」、選択肢3の「3つに分割」、選択肢4の「音を鳴らす」はどれも誤りなのー。
| 選択肢 | 判定 | 理由 |
|---|---|---|
| 1 | ✗ | 小さな窓の機能ではない |
| 2 | ✓ | 問い合わせの中の問い合わせ |
| 3 | ✗ | 3つに分割する命令ではない |
| 4 | ✗ | 音を鳴らす設定ではない |
オリジナル問題2(CTE)
CTE(WITH句)に関する次の記述のうち、正しいものはどれか。
- CTEはWITH句で一時的な結果に名前をつけ、問い合わせを読みやすくするしくみである
- CTEは画面の色をその場だけ一時的に変えるために使う機能のことだとされているものである
- CTEはデータを必ず暗号化して保存するための命令のことだとされているものである
- CTEは表を必ず3つに増やして保持するための設定のことだとされているものである
解答は 1 だよー。
CTEは、WITH句を使って、一時的な結果に名前をつけて問い合わせを読みやすくするしくみなのー。下書きメモに名前をつけておく感じだよー。
選択肢2の「色を変える」、選択肢3の「暗号化する」、選択肢4の「表を3つに増やす」はどれも誤りなのー。
| 選択肢 | 判定 | 理由 |
|---|---|---|
| 1 | ✓ | WITHで一時結果に名前をつけ読みやすく |
| 2 | ✗ | 色を変える機能ではない |
| 3 | ✗ | 暗号化の命令ではない |
| 4 | ✗ | 表を増やす設定ではない |
オリジナル問題3(再帰CTE)
再帰CTE(WITH RECURSIVE)に関する次の記述のうち、正しいものはどれか。
- 再帰CTEは画面を必ず3回続けて点滅させるためだけの設定のことだとされているものである
- 再帰CTEはデータを必ず1か所だけ削除するための命令のことだとされているものである
- 再帰CTEはWITH RECURSIVEで、組織ツリーなどの階層を上から順にたどれる
- 再帰CTEは音量を自動で大きく上げるためだけの機能のことだとされているものである
解答は 3 だよー。
再帰CTEは、WITH RECURSIVEと書いて、組織ツリー(上司→部下→そのまた部下…)のような階層を、上から順にたどって展開できるのー。
選択肢1の「3回点滅」、選択肢2の「削除する命令」、選択肢4の「音量を上げる」はどれも誤りなのー。
| 選択肢 | 判定 | 理由 |
|---|---|---|
| 1 | ✗ | 点滅の設定ではない |
| 2 | ✗ | 削除する命令ではない |
| 3 | ✓ | 階層を上から順にたどって展開 |
| 4 | ✗ | 音量を上げる機能ではない |
まとめ
押さえどころ
- 🔴 サブクエリの種類 = 問い合わせの中の問い合わせ。スカラ・IN/EXISTS・相関(相関は性能に注意)。
- 🔴 CTEと再帰CTE = CTEはWITHで一時結果に名前をつけ読みやすく。再帰CTEは階層をたどる。
- 🟡 IN/EXISTSとMySQL対応 = 多くはEXISTSが性能良。MySQLは8.0からCTE対応。
次に学ぶ
執筆: SikakuQuest編集部