はじめに、この記事が目指すゴールを共有させてください。
この記事は、単なるSQL構文の解説書ではありません。世の中には素晴らしいSQLの入門書がたくさんありますし、各キーワードの役割を覚えることはもちろん大切です。
しかし、応用情報技術者試験や高度IT試験の「データベース問題」で本当に求められるのは、その知識をいかにして“正解”に結びつけるか、という実践的なスキルです。
特に、多くの受験者が時間を溶かしてしまうSQLの空欄補充問題。
私たちは、この問題を単なる暗記ゲームではなく、「問題文に散りばめられたヒントを基に、空欄に入るピースを論理的に見つけ出す、知的なパズル」だと考えています。
そこで、この記事では以下の3つをあなたに提供することを約束します。
-
- パターン化された「解法テクニック」:空欄の“場所”と“前後の文脈”から、正解候補のキーワードを瞬時に絞り込む方法。
- 再現性のある「思考プロセス」:なぜそのキーワードが正解なのか?その根拠を言語化し、初見の問題にも対応できる応用力を養うための頭の使い方。
- 得点源に変える「自信」:SQL問題への苦手意識を克服し、「よし、来た!」と楽しめるようになるためのマインドセット。
この記事を読み終える頃、あなたはSQLの空欄を前にして闇雲に悩むことはなくなるでしょう。
代わりに、名探偵のように論理の糸をたぐり寄せ、パズルの最後の1ピースをはめるように、確信をもって答えを導き出せるようになっているはずです。
さあ、一緒にSQLパズルを解き明かすための「思考法」をマスターしていきましょう!
目次
- 1 1. イントロダクション:そのデータベース問題、"宝の山"かもしれません
- 2 2. 結論ファースト:SQL空欄補充は「場所」と「文脈」のパターン認識ゲームだ
- 3 3. 大図解:SQLクエリは"この順番"で処理される!戦場マップを手に入れよ
- 4 4. なぜ?がわかる深掘り解説:頻出"空欄"パターン別 思考トレース
- 5 5. 厳選過去問と思考トレース:名探偵のように、論理で解き明かす
- 6 6. 未来を予測する出題予想:次の武器「ウィンドウ関数」と「CTE」を知る
- 7 7. 知識を体系化する関連マップ:SQLキーワードの相関図
- 8 8. あなただけの学習ロードマップ:レベル別・最短攻略コース
- 9 9. 理解度チェック&チャレンジクイズ
- 10 解答と解説
- 11 関連
1. イントロダクション:そのデータベース問題、"宝の山"かもしれません
応用情報技術者試験、午後問題。どの分野を選択するかは、合否を分ける大きな戦略の一つですよね。
その中でも「データベース」は、多くの参考書で“安定択”として紹介されます。なぜなら、出題されるテーマや形式がある程度決まっており、対策すれば着実にスコアを積み上げられるからです。
…しかし、現実はどうでしょうか?
「E-R図はなんとなくわかるけど、SQLの長いクエリを見ると頭が真っ白になる…」
「JOINや副問合せが絡むと、もう何が何だか…」
「結局、空欄補充は“勘”で埋めてしまっている」
そんな経験はありませんか?
“安定択”のはずが、気づけば“鬼門”になっている。その最大の原因こそ、SQLの空欄補充問題です。
ですが、もし…。
この"お決まりの"SQL問題に、“お決まりの解法パターン”があったとしたら、どうでしょう?
実は、あるんです。SQLの空欄補充問題は、問題文の構成やキーワードの配置に一定の「クセ」があります。その「クセ」を見抜く眼さえ養えば、複雑に見えるクエリも、驚くほどシンプルに解き明かすことができます。
この記事では、その「クセ」を見抜くための思考法を、あなたに伝授します。
もう“勘”に頼る必要はありません。論理的な根拠をもって、自信を持って解答できるようになりましょう。あなたの“鬼門”を“宝の山”に変える旅へ、いざ出発です!
2. 結論ファースト:SQL空欄補充は「場所」と「文脈」のパターン認識ゲームだ
では、SQLの空欄補充問題を攻略する核心を、単刀直入にお伝えします。
それは、
キーワードが入る「場所」(どの句の空欄か)と、
その「前後の文脈」が持つ“必出パターン”を掴むこと。
これに尽きます。
どういうことか?
例えば、あなたがミステリー小説を読んでいるとします。もし「犯人は、被害者のすぐ隣に住んでいた______だ」という一文があれば、空欄には「人物」や「隣人」といった言葉が入ると、ほぼ確信できますよね。まさか「犬」や「机」が入るとは思わないはずです。
SQLの空欄補充も、これと全く同じです。
GROUP BY
句の後ろの空欄には、ほぼ間違いなく「グループ化のキーとなる列名」が入る。WHERE
句で絞り込んだ結果を、さらにグループ単位で絞り込む文脈なら、HAVING
句の出番。- 複数の表を「つなぐ」という文脈なら、
JOIN
が登場し、その直後のON
句の空欄には「両方の表に共通する列(キー)」が入る。
このように、空欄がどの「場所」にあり、どんな「文脈」で使われているかを見抜けば、正解キーワードの候補は劇的に絞られます。
つまり、闇雲に全てのSQL構文を思い出すのではなく、正解の「確率」が高いキーワードから当てはめていく思考法こそが、最短・最強の攻略ルートなのです。
次のセクションから、この「必出パターン」を一つひとつ、徹底的に解き明かしていきます。
3. 大図解:SQLクエリは"この順番"で処理される!戦場マップを手に入れよ
複雑に見えるSQL文も、実はコンピュータ内部では厳格なルール(処理順序)に従って動いています。私たちが書く順番(SELECT
が最初)と、コンピュータが解釈する順番は違う、という点が非常に重要です。
この「論理的な処理順序」こそ、SQL空欄補充問題を解くための"戦場マップ"となります。まずはこのマップを手に入れましょう。
【SQLクエリの論理的な処理順序マップ】
(↓ここに本来は図が入るイメージです)
ステップ1:FROM / JOIN
まず、どのテーブル(台帳)からデータを取ってくるかを決定します。複数のテーブルがある場合は、ここですべて結合(JOIN)して、一枚の巨大な仮想テーブルを作成します。
➡️ (思考ポイント:ここでの空欄は「どのテーブルと、どのキーで結合するか」が問われる)
ステップ2:WHERE
ステップ1で作った巨大なテーブルから、「条件に合う行だけ」を絞り込みます。ここではまだグループという概念はなく、一行一行を個別審査するイメージです。
➡️ (思考ポイント:個人(行)単位の条件分岐。副問合せ(IN, EXISTS)が頻出!)
ステップ3:GROUP BY
ステップ2で絞り込んだ行たちを、指定したキー(例:部門ごと、商品カテゴリごと)でグループ分けします。ここから集計作業の準備に入ります。
➡️ (思考ポイント:集計の“軸”を指定する場所。SELECT句に集約関数があれば、まずここを疑う)
ステップ4:HAVING
ステップ3で作成したグループに対して、「条件に合うグループだけ」を絞り込みます。WHERE
が“個人戦”なら、HAVING
は“団体戦”のフィルターです。
➡️ (思考ポイント:必ずGROUP BYとセットで登場。集約関数(COUNT, SUM等)を使った条件が入る)
ステップ5:SELECT
ステップ4で生き残ったグループから、最終的にどの列を表示するかを決定します。集約関数(COUNT
, SUM
など)による計算もここで行われます。
➡️ (思考ポイント:最終的なアウトプットを決める場所。CASE式による条件分岐も狙われる)
ステップ6:ORDER BY
最終結果を、指定した列を基準に並べ替えます。すべての処理が終わった後の、最後の味付けです。
➡️ (思考ポイント:並び順の指定。ASC(昇順)かDESC(降順)か)
いかがでしょうか?この「FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY」という流れを頭に入れておくだけで、SQL文の見通しが劇的に良くなります。
このマップのどこに空欄があるのか?それによって、入るべきキーワードの候補は自ずと見えてくるのです。次の章から、各ステップで狙われる空欄のパターンを具体的に見ていきましょう。
4. なぜ?がわかる深掘り解説:頻出"空欄"パターン別 思考トレース
4-1. 【場所:FROM / JOIN句】 すべてのデータの出発点
FROM
句は、クエリがどのテーブルを扱うかを宣言する、いわば「食材選び」のステップです。ここの空欄は、基本から応用まで様々なパターンが考えられます。
思考パターン①:テーブルは一つか?複数か?
まず最初に考えるべきは、クエリが扱っているテーブルの数です。
- テーブルが1つ → 空欄には単純にテーブル名が入ります。これは最も基本的な形です。
- テーブルが2つ以上 → ほぼ確実に
JOIN
キーワードが登場します。応用情報で問われるのはこのパターンです。
思考パターン②:「どのJOINを使うか?」を文脈から見抜く
JOIN
が必要だと判断したら、次はその種類を考えます。応用情報で特に重要なのはINNER JOIN
とLEFT JOIN
(またはLEFT OUTER JOIN
)の使い分けです。
例:社員テーブル と 部署テーブル
「両方のテーブルに存在するデータだけを取り出す」結合です。
文脈:「部署に所属している社員の一覧」「商品を購入したことがある顧客リスト」など、関連が明確なデータだけが欲しい場合に使われます。
SQL例:
... FROM 社員テーブル a INNER JOIN 部署テーブル b ON a.部署コード = b.部署コード
「左側のテーブルの全データと、それに紐づく右側のテーブルのデータ」を取り出します。右側に紐づくデータがなければ
NULL
が入ります。文脈:「すべての社員の部署名(部署未所属の社員も含む)」「すべての商品の売上(一度も売れていない商品も含む)」など、マスター側のデータを軸に情報を見たい場合に使われます。
SQL例:
... FROM 社員テーブル a LEFT JOIN 部署テーブル b ON a.部署コード = b.部署コード
空欄がJOIN
の前後にあれば、問題文の「~も含む」「~がないものも表示」といった表現が、LEFT JOIN
を選択する強力なヒントになります。
思考パターン③:JOINの相棒「ON」を疑え
JOIN
キーワードが出てきたら、その直後には必ずON
句が続きます。ON
句の空欄で問われるのは、100%「テーブル同士を繋ぐための結合キー」です。
... ON a.[ ア ] = b.[ イ ]
このような空欄があったら、E-R図を見て、2つのテーブルを関連付けている線(リレーション)の両端にある属性(列名)を探せば、それが答えです。例えば「社員テーブルの部署コード」と「部署テーブルの部署コード」といったペアですね。
思考パターン④:(応用)FROM句の中のSELECT文
少し複雑な問題では、FROM
句の直後にテーブル名ではなく、括弧()
で囲まれたSELECT
文(副問い合わせまたは導出表と呼ばれます)が入ることがあります。
... FROM (SELECT ... FROM ... ) AS 別名 ...
これは「先に中間的な集計や絞り込みを行った"仮想的なミニテーブル"をその場で作り、それを使ってさらに処理を続けたい」という文脈で使われます。GROUP BY
した結果を、さらに別のテーブルとJOIN
したい場合などが典型例です。
FROM
句の直後が空欄で、その後にAS
やテーブルの別名が続くようなら、このパターンを疑ってみましょう。
4-2. 【場所:WHERE句】 データの行方を決める最初の関所
WHERE
句は、FROM
句で作られた巨大なテーブルから、条件に合う行をふるいにかける役割を持ちます。いわば「個人面接」のステップ。ここでの空欄は、条件式の作り方が問われます。
思考パターン①:単純な条件式(基本のキ)
まずは基本です。空欄が「列名 〇 値」のような形なら、比較演算子(=, <>, >, <
など)や、範囲を指定するBETWEEN
、文字列の部分一致を調べるLIKE
が入る可能性が高いです。これはウォーミングアップですね。
... WHERE 売上日 BETWEEN '2025-04-01' AND '2025-04-30'
思考パターン②:最重要!副問い合わせを使いこなす
応用情報で最も狙われるのが、副問い合わせ(Subquery)を使った条件式です。WHERE
句の条件に、別のSELECT
文の結果を利用するパターンで、特にIN
とEXISTS
は頻出中の頻出です。
IN
は、ある列の値が「( )内に指定された値のリストのいずれかに含まれているか」をチェックします。文脈:「東京または大阪に支社がある部署の社員」「A商品またはB商品を購入した顧客」など、複数の候補のうち、どれか一つにでも当てはまるものを探すときに使います。
思考法:空欄の前が列名で、後ろが`( )`で囲まれた
SELECT
文なら、まずIN
を疑いましょう。「~のいずれかに一致する」という文脈を探します。SQL例:
... WHERE 部署コード IN (SELECT 部署コード FROM 部署マスタ WHERE 所在地 = '東京')
(→ 部署コードが、'東京'にある部署コードのリストに含まれているか?)
EXISTS
は、「( )内の副問い合わせを実行した結果、一件でも行が返ってくるか」をチェックします。値そのものではなく、関連データの「存在有無」を問うのがポイントです。文脈:「一度でも商品を購入したことがある顧客」「講習会に申し込みがある講座」など、「~したことがある」「~が存在する」という事実を確認したいときに使います。
思考法:
EXISTS
の副問い合わせは、主問い合わせのテーブルと関連付ける相関副問合せになることがほとんどです。... WHERE EXISTS (SELECT * FROM 注文テーブル WHERE 注文テーブル.顧客番号 = 顧客マスタ.顧客番号)
のように、副問い合わせの中に主問い合わせの列が登場したら、EXISTS
が濃厚です。SQL例:
... FROM 顧客マスタ a WHERE EXISTS (SELECT * FROM 注文履歴 b WHERE a.顧客番号 = b.顧客番号)
(→ 顧客マスタの各行に対して、同じ顧客番号を持つ注文履歴が存在するか?)
【使い分けのポイント】
ざっくり言うと、IN
は「値」のリストとの比較、EXISTS
は関連する「行」の存在チェックです。どちらも同じ結果を得られることも多いですが、問題のE-R図や前後のSQL文から、どちらの書き方が自然か(あるいは、どちらかでないと書けないか)を判断するのが腕の見せ所です。
4-3. 【場所:GROUP BY / HAVING句】 集計と絞り込みの最強コンビ
GROUP BY
とHAVING
は、必ずセットで学習すべき兄弟のような句です。役割は「グループ化」と「グループに対する絞り込み」。ここを制する者は、集計問題を制します。
思考パターン①:GROUP BYを呼ぶ「集約関数」のサイン
まずGROUP BY
句です。これは、特定の列の値が同じ行を一つのグループにまとめる役割を持ちます。では、どんな時に必要になるのでしょうか?
鉄則:SELECT
句に集約関数(COUNT
, SUM
, AVG
, MAX
, MIN
)と、それ以外の通常の列名が混在している場合、GROUP BY
句は必須です。
SELECT 部署名, COUNT(社員番号) FROM ...
上記のように、「部署名」という通常の列と、「社員番号の件数」という集約結果を同時に表示したい場合、コンピュータは「どの単位で人数を数えればいいの?」と迷ってしまいます。そこで、GROUP BY 部署名
と指定することで、「部署名ごとにグループ化して、そのグループ内で社員数を数えてね」と指示してあげるわけです。
空欄の法則:GROUP BY
句の空欄に入るのは、SELECT
句にある「集約関数で囲まれていない列」です。これは非常に強力な法則なので、絶対に覚えてください。
思考パターン②:HAVINGは「グループへの条件指定」
次にHAVING
句です。これは、GROUP BY
で作られたグループの中から、さらに条件に合うものだけを絞り込む役割を持ちます。
ここで、多くの人が「あれ、条件指定ならWHERE
句じゃダメなの?」と疑問に思います。両者の違いを明確にしましょう。
- WHERE句:グループ化する前に、一行一行を審査する。「個人戦」のフィルター。
➡️ (例)WHERE 役職 = '部長'
(役職が部長の“人”をまず集める) - HAVING句:グループ化した後に、グループごと審査する。「団体戦」のフィルター。
➡️ (例)HAVING COUNT(*) >= 5
(メンバーが5人以上の“部署”だけを残す)
重要:HAVING
句の条件式には、必ず集約関数が含まれます。これも鉄則です。
文脈のヒント:問題文に「~ごとの平均点が70点以上の...」「人数が3人以上の部署」「合計金額が10万円を超える顧客」といった、集計結果に対する条件が書かれていたら、それはHAVING
句の出番が来たというサインです。
SQL例:
SELECT 部署名, COUNT(*)
FROM 社員テーブル
WHERE 入社年度 >= 2020
-- (個人を絞り込み)
GROUP BY 部署名
HAVING COUNT(*) >= 3
; -- (グループを絞り込み)
この「WHEREで個人戦、GROUP BYでチーム分け、HAVINGで団体戦」という流れを掴めば、もう迷うことはありません。
4-4. 【場所:SELECT句】 最終アウトプットの化粧師
SELECT
句は、クエリで表示する列を最終的に定義する場所です。処理順序では後ろの方ですが、私たちが書くときは一番最初に来る、まさにクエリの「顔」です。ここの空欄では、何を表示したいのかを的確に表現する能力が問われます。
思考パターン①:基本の列名と、お馴染みの集約関数
最もシンプルなのは、表示したい列名をカンマ区切りで並べるパターンです。SELECT 社員番号, 氏名, ...
といった形ですね。
また、GROUP BY
句がある場合は、COUNT(列名) AS 件数
や SUM(金額) AS 合計金額
のように、集約関数とその結果に名前をつける(AS
)パターンが頻出です。これは 4-3 で見た通りですね。
思考パターン②:SQLのIF文、「CASE」式を使いこなす
SELECT
句の空欄で差がつくのが、CASE
式です。これは、SQL文の中に「IF-THEN-ELSE」のような条件分岐ロジックを埋め込むための強力な武器です。
文脈のヒント:問題の要求仕様に「~の場合はAと表示」「~の場合はBと表示」「それ以外はCと表示」のように、条件によって表示内容を変えたい、という記述があれば、CASE
式の出番を強く疑ってください。
CASE
で始まりEND
で終わる、一塊の処理です。
CASE
WHEN 条件式1 THEN '結果1'
WHEN 条件式2 THEN '結果2'
ELSE 'その他の場合の結果'
END
SQL例:成績テーブルから、点数に応じて「優」「良」「可」を判定して表示する
SELECT
学生番号,
点数,
CASE
WHEN 点数 >= 90 THEN '優'
WHEN 点数 >= 70 THEN '良'
ELSE '可'
END AS 評価
FROM
成績テーブル;
このように、元のテーブルには存在しない「評価」という新しい列を、条件に応じて動的に作り出すことができます。SELECT
句の空欄が少し長く、文脈に条件分岐のニュアンスがあれば、このCASE
式がピタリとはまることが多いです。
思考パターン③:(応用)スカラー副問い合わせ
もう一つ、応用的なテクニックとして、SELECT
句の中に直接SELECT
文を埋め込む「スカラー副問い合わせ」があります。これは、必ず1行1列の結果だけを返すSELECT
文で、ある行のデータに関連する、別のテーブルのピンポイントな値を取得したいときに使います。
例:「社員一覧を表示する際に、各社員が所属する部署の"平均年齢"も一緒に表示する」など。
これは少し複雑なので、「SELECT
句にも副問い合わせが入ることがあるんだな」くらいに頭の片隅に置いておけば、応用情報レベルでは十分でしょう。
4-5. 【その他】JOINの相棒「ON」と、更新系SQLの作法
最後に、これまで解説した句以外で狙われやすい、いくつかの重要パターンを見ていきましょう。
思考パターン①:JOINの相棒、ON
句(再確認)
4-1でも触れましたが、JOIN
句にはON
句がペアで登場し、テーブル間の結合条件を定義します。ここの空欄はサービス問題に近いです。
... FROM テーブルA a JOIN テーブルB b ON a.[ ア ] = b.[ イ ]
空欄の法則:空欄 [ア] と [イ] に入るのは、2つのテーブルを繋ぐ「外部キー」と「主キー」のペアです。E-R図を見て、テーブル間を結ぶ線がどの列(属性)に繋がっているかを確認すれば、一瞬で見抜けます。
思考パターン②:データを変更する「更新系SQL」
応用情報では稀ですが、データの参照(SELECT
)だけでなく、追加・更新・削除を行うSQL(DML: Data Manipulation Language)が問われることもあります。構文がシンプルなので、キーワードさえ覚えていれば得点源になります。
新しい行を追加します。「~を登録する」という文脈で登場します。
SQL例:INSERT INTO 社員テーブル (社員番号, 氏名) VALUES ('E123', '情報 太郎');
狙われる空欄:INTO
やVALUES
といった、構文を構成するキーワードそのものが狙われやすいです。
既存の行の値を変更します。「~を更新する」「~に変更する」という文脈で登場します。
SQL例:UPDATE 社員テーブル SET 部署コード = 'D002' WHERE 社員番号 = 'E123';
狙われる空欄:更新する列を指定するSET
は最頻出の空欄候補です。また、どの行を更新するのかを指定するWHERE
句の条件ももちろん問われます。
既存の行を削除します。「~を削除する」という文脈で登場します。
SQL例:DELETE FROM 社員テーブル WHERE 在籍状況 = '退職';
狙われる空欄:どのテーブルから削除するかを指定するFROM
が空欄になることがあります。UPDATE
と同様、どの行を消すかを決めるWHERE
句が非常に重要です。
これで、SQL空欄補充問題で遭遇するであろう、ほとんどのパターンを地図に収めることができました。次の章では、この地図を片手に、実際の過去問という名の冒険に出発しましょう!
5. 厳選過去問と思考トレース:名探偵のように、論理で解き明かす
理論はもう十分です。ここからは、実際の過去問(※)を使って、これまで学んだ思考プロセスを実践してみましょう。頭の中で、こんな風に考えていけば正解にたどり着ける、という流れを体感してください。
※ ここでは、応用情報技術者試験で頻出のロジックを基にした典型的な問題例を使用します。
問題設定
あるECサイトのデータベースには、商品を管理する「商品マスタ」と、注文明細を管理する「注文明細テーブル」があります。
- 商品マスタ (商品コード, 商品名, 単価)
- 注文明細テーブル (注文番号, 行番号, 商品コード, 数量)
【要件】一度でも注文されたことがある商品の「商品コード」と「商品名」を一覧表示するSQL文を完成させなさい。
【SQL文】
SELECT
T1.商品コード,
T1.商品名
FROM
商品マスタ AS T1
WHERE
[ a ] (SELECT * FROM 注文明細テーブル AS T2 WHERE T1.商品コード = T2.[ b ])
思考トレース・スタート!
【ステップ1】問題の要件を分解する
まず、問題文のキモはどこでしょう?
「一度でも注文されたことがある商品」という部分ですね。これはつまり、商品マスタにある商品コードが、注文明細テーブルに“存在する”かどうかをチェックせよ、と言い換えることができます。
【ステップ2】空欄 [a] の候補を絞り込む
- 場所の確認:空欄 [a] は
WHERE
句にあり、その後ろには( )
で囲まれたSELECT
文(副問い合わせ)が続いています。 - パターンの適用:セクション4-2で学んだ「WHERE句の副問い合わせパターン」を思い出します。この形の最有力候補は
IN
とEXISTS
でしたね。 - 文脈の判断:
- もし
IN
を使うなら、WHERE T1.商品コード IN (SELECT 商品コード FROM ...)
のように、値のリストと比較するはずです。しかし、今回の副問い合わせはSELECT *
となっており、値のリストを返していません。 - 一方、
EXISTS
は「副問い合わせの結果が1行でも返ってくるか(=存在するか)」をチェックする演算子でした。今回の要件「一度でも注文されたことがある(=注文明細が存在する)」にピッタリ合致します。
- もし
- 結論:この文脈では
EXISTS
が最適だと判断できます。
【ステップ3】空欄 [b] の候補を絞り込む
- 場所の確認:空欄 [b] は、副問い合わせ内の
WHERE
句にあります。WHERE T1.商品コード = T2.[ b ]
という形です。 - パターンの適用:これは、主問い合わせのテーブル(
T1
=商品マスタ)と、副問い合わせのテーブル(T2
=注文明細テーブル)を関連付ける「相関副問合せ」の形です。これはセクション4-1の「ON句」の考え方と全く同じです。2つのテーブルを繋ぐキーを探します。 - E-R図(テーブル定義)の確認:商品マスタと注文明細テーブルを繋ぐ共通の列は、明らかに「商品コード」です。
- 結論:したがって、空欄 [b] に入るのは
商品コード
で間違いありません。
【最終解答】
以上の思考プロセスにより、答えは以下のように導き出せます。
- a:
EXISTS
- b:
商品コード
いかがでしたか?闇雲に考えるのではなく、空欄の「場所」と「文脈」からパターンを適用し、論理的に答えを絞り込んでいく。この感覚をぜひ、ご自身の学習にも取り入れてみてください。
6. 未来を予測する出題予想:次の武器「ウィンドウ関数」と「CTE」を知る
ここまでの知識で、応用情報技術者試験のSQL問題の9割以上は対応可能です。しかし、IT技術は常に進化しています。ここでは、あなたの知的好奇心を刺激し、ライバルに一歩差をつけるための「未来の武器」を2つ、ご紹介します。
これらは高度試験や実務では既に常識となりつつあり、いつ応用情報レベルに降りてきてもおかしくありません。
未来の武器①:ウィンドウ関数 (分析関数)
「グループごとに集計する」のがGROUP BY
でした。それに対して「グループ内の順位付け」や「グループ内での前後の行との比較」を可能にするのがウィンドウ関数です。
文脈のヒント:「部署ごとに給与の高い順にランキングを付けたい」「商品カテゴリごとに、売上の累計を計算したい」といった、集計と順位付けが同時に求められたら、ウィンドウ関数の出番です。
SQL例:部署ごとに給与の高い順でランキングを付ける
SELECT
氏名,
部署名,
給与,
RANK() OVER (PARTITION BY 部署名 ORDER BY 給与 DESC) AS 部署内ランク
FROM
社員テーブル;
PARTITION BY 部署名
:これが「部署ごと」に集計範囲(ウィンドウ)を区切る、という意味です。GROUP BY
の親戚のようなものですね。ORDER BY 給与 DESC
:そのウィンドウの中で、何順に並べるかを指定します。RANK()
:そして、その順位を計算します。
GROUP BY
と違って行を集約しないため、元の行の情報を残したまま、ランキングなどの付加情報を付け加えられるのが大きなメリットです。
未来の武器②:共通テーブル式 (CTE / WITH句)
FROM
句の中にSELECT
文を埋め込む「副問い合わせ」は、入れ子(ネスト)が深くなると非常に読みにくくなる、という弱点がありました。
この弱点を克服し、SQLを劇的に読みやすくするのが共通テーブル式(CTE)、通称WITH
句です。
思考法:複雑なSQL文を、いくつかの「部品」に分割して組み立てるイメージです。最初にWITH
句で部品(一時的な仮想テーブル)を定義し、メインのSELECT
文ではその部品名をシンプルに使うことができます。
SQL例:部門ごとの合計売上を計算し、その結果を使って部署マスタと結合する
WITH 部門別合計売上 (部門コード, 合計売上) AS (
SELECT
部門コード,
SUM(売上額)
FROM
売上テーブル
GROUP BY
部門コード
)
SELECT
D.部門名,
S.合計売上
FROM
部門マスタ AS D
JOIN
部門別合計売上 AS S ON D.部門コード = S.部門コード;
いかがでしょうか。WITH
句を使うことで、まず「部門別合計売上」という部品を作り、そのあとでじっくりメインの処理を記述できます。これにより、SQL文全体の可読性が飛躍的に向上します。
今は「こんな便利なものがあるんだ」という程度の理解でOKです。しかし、この2つを知っているだけで、あなたは他の受験者より確実に一歩先を行っていますよ。
7. 知識を体系化する関連マップ:SQLキーワードの相関図
お疲れ様です。ここまでで、SQL空欄補充を解くための様々なキーワード(武器)を手に入れてきましたね。最後に、それらの武器がどのカテゴリーに属し、どのように関連しているのかを一枚のマップに整理し、知識を体系化しましょう。
SQLコマンド体系マップ
-
- DML (Data Manipulation Language) - データ操作言語
SELECT
(データ参照) - 最も重要!FROM
- どのテーブルから?JOIN
- テーブルを結合 (INNER
,LEFT
)ON
- 結合のキーを指定
WHERE
- どの行を? (個人戦フィルター)IN
- 値のリストに含まれるか?EXISTS
- 関連データが存在するか?
GROUP BY
- どの単位でグループ化?HAVING
- どのグループを? (団体戦フィルター)SELECT
- どの列を表示?CASE
- 条件によって表示内容を変更- 集約関数 (
COUNT
,SUM
,AVG
...)
ORDER BY
- どの順で並べる?
INSERT
(データ追加)INTO
,VALUES
UPDATE
(データ更新)SET
,WHERE
DELETE
(データ削除)FROM
,WHERE
- DML (Data Manipulation Language) - データ操作言語
-
- DDL (Data Definition Language) - データ定義言語 (今回は深入りしませんでした)
CREATE
- テーブルなどを作成ALTER
- テーブルなどの定義を変更DROP
- テーブルなどを削除
- DDL (Data Definition Language) - データ定義言語 (今回は深入りしませんでした)
- DCL (Data Control Language) - データ制御言語 (今回は深入りしませんでした)
GRANT
- 権限を付与REVOKE
- 権限を剥奪
このマップを時々眺めることで、「ああ、HAVING
はGROUP BY
とセットだったな」「IN
やEXISTS
はWHERE
句で使う武器だったな」という風に、知識のつながりを思い出しやすくなります。ぜひ、あなたの頭の中のSQL知識を整理整頓するために活用してください。
8. あなただけの学習ロードマップ:レベル別・最短攻略コース
この記事で解説した思考法を身につけるための、具体的な学習ステップをレベル別に提案します。ご自身の現在地に合わせて、最適なコースを選んでみてください。
コース1:SQL苦手意識克服コース (初学者向け)
ゴール:複雑なSQLへのアレルギーをなくし、「これなら解けるかも」という自信を持つ。
ステップ①:SELECT, FROM, WHERE の三種の神器を固める
まずは基本中の基本から。1つのテーブルを対象に、WHERE
句で様々な条件(=, >, BETWEEN, LIKE
など)を指定してデータを抽出する練習を繰り返しましょう。ここが全ての土台です。
ステップ②:INNER JOIN で「表の合体」に慣れる
次に、2つのテーブルをINNER JOIN
で結合する練習です。「社員テーブルと部署テーブルを結合して、社員名と部署名を表示する」といった、最もシンプルな結合パターンをマスターしましょう。この段階ではLEFT JOIN
は一旦忘れてOKです。
ステップ③:GROUP BY と COUNT で「集計の第一歩」を踏み出す
最後に、「部署ごとの人数」「商品カテゴリごとの品数」など、GROUP BY
とCOUNT(*)
を使った簡単な集計に挑戦します。まずは「グループ化して数える」という感覚を掴むことが目標です。
コース2:得点力盤石!応用マスターコース (中級者向け)
ゴール:SQLを安定した得点源に変え、合格を盤石にする。
ステップ①:LEFT JOIN と 副問い合わせ(IN/EXISTS)を使い分ける
INNER JOIN
との違いは何か?IN
とEXISTS
のどちらが適切か?過去問を題材に、「なぜ、この問題ではこちらを使うのか」を自分の言葉で説明できるレベルを目指しましょう。本記事の思考トレースが役に立つはずです。
ステップ②:HAVING と CASE式を武器にする
「集計結果に対する絞り込み(HAVING
)」と「条件に応じた表示の切り替え(CASE
)」は、応用情報SQLの頻出応用パターンです。これらのキーワードが登場する過去問を重点的に解き、自由自在に使いこなせるようになりましょう。
ステップ③:時間を計って過去問を解き、思考プロセスを再現する
最終ステップは、本番同様のプレッシャーの中で、これまで学んだ思考プロセスを実践することです。時間を計って問題を解き、答え合わせの際には「なぜその答えになったか」の筋道を、自分の頭で再現できるかを確認しましょう。これができれば、あなたはもうSQLマスターです。
9. 理解度チェック&チャレンジクイズ
お疲れ様でした!いよいよ最終関門です。ここであなたのSQL読解力がどれだけ向上したか、腕試しをしてみましょう。本記事で解説した「思考法」を頼りに、正解を導き出してください。
第1問:JOINの使い分け
【要件】全部署の「部署名」と、各部署に所属する「社員数」を一覧表示したい。まだ社員が一人も所属していない部署もリストに含め、その場合、社員数は0と表示すること。
【テーブル】
・部署マスタ (部署コード, 部署名)
・社員マスタ (社員番号, 氏名, 部署コード)
【SQL文】
SELECT
T1.部署名,
COUNT(T2.社員番号) AS 社員数
FROM
部署マスタ AS T1 [ ア ] 社員マスタ AS T2
ON T1.部署コード = T2.部署コード
GROUP BY
T1.部署名;
空欄 [ ア ] に入る最も適切な句はどれか?
- INNER JOIN
- LEFT JOIN
- RIGHT JOIN
- CROSS JOIN
第2問:HAVINGとWHEREの違い
【要件】商品カテゴリごとに平均単価を計算し、その平均単価が5,000円以上のカテゴリだけを表示したい。
【テーブル】
・商品マスタ (商品コード, 商品名, カテゴリ, 単価)
【SQL文】
SELECT
カテゴリ,
AVG(単価) AS 平均単価
FROM
商品マスタ
GROUP BY
カテゴリ
[ イ ]
AVG(単価) >= 5000;
空欄 [ イ ] に入る最も適切な句はどれか?
- WHERE
- HAVING
- AND
- ON
解答と解説
↓(下にスクロールして確認してください)↓
第1問の解答・解説
正解:2. LEFT JOIN
【思考プロセス】
この問題の最大のヒントは、「まだ社員が一人も所属していない部署もリストに含め」という一文です。これは、「主軸となるテーブルは部署マスタであり、その全件を表示する必要がある」ということを意味します。
左側(FROM
句の最初)に書かれた部署マスタ
を基準に、それに紐づく社員マスタ
の情報を結合する必要があるため、左側を正とするLEFT JOIN
が正解となります。
もしINNER JOIN
を選ぶと、社員が一人もいない部署(社員マスタに対応するレコードがない部署)は結果から除外されてしまいます。
第2問の解答・解説
正解:2. HAVING
【思考プロセス】
空欄 [イ] の直後にある条件式 AVG(単価) >= 5000
に注目します。AVG()
は集約関数です。
セクション4-3の鉄則を思い出してください。「集約関数を使った条件式は、HAVING
句にしか記述できない」でしたね。
WHERE
句はGROUP BY
でグループ化する前の「個人戦」フィルターであり、集約関数を使うことはできません。GROUP BY
後の「団体戦」フィルターであるHAVING
句が、この場面で使うべき唯一の正解となります。