戦国IT - 情報処理技術者試験の過去問対策サイト
ブログお知らせお問い合わせ料金プラン

応用情報技術者 2021年 秋期 午前229


問題文

“部門別売上”表から、部門コードごと、期ごとの売上を得るSQL文はどれか。
応用情報技術者 2021年 秋期 午前2 問29の問題画像

選択肢

SELECT 部門コード, '第1期' AS期, 第1期売上 AS 売上
 FROM 部門別売上
 INTERSECT
 (SELECT 部門コード, '第2期' AS 期, 第2期売上 AS 売上
  FROM 部門別売上)
 ORDER BY 部門コード, 期
SELECT 部門コード, '第1期' AS期, 第1期売上 AS 売上
 FROM 部門別売上
 UNION
 (SELECT 部門コード, '第2期' AS期, 第2期売上 AS 売上
  FROM 部門別売上)
 ORDER BY 部門コード, 期
(正解)
SELECT A.部門コード, '第1期' AS期, A.第1期売上 AS 売上
 FROM 部門別売上 A
 CROSS JOIN
 (SELECT B.部門コード, '第2期' AS 期, B.第2期売上 AS 売上
  FROM 部門別売上 B) T
 ORDER BY 部門コード, 期
SELECT A.部門コード, '第1期' AS期, A.第1期売上 AS 売上
 FROM 部門別売上 A
 INNER JOIN
 (SELECT B.部門コード, '第2期' AS期, B.第2期売上 AS 売上
  FROM 部門別売上 B) T ON A.部門コード = T.部門コード
 ORDER BY 部門コード, 期

🔒 解説は解答すると表示されます

列から行への変換【午前2解説】

正解の理由

与えられた問合せ結果は「各部門について第1期と第2期を別行に並べる(ワイド形式をロング形式に変換)」ことを求めています。これは同じ列構成(部門コード、期、売上)を持つ2つのSELECT結果を縦に連結すれば得られるため、複数行を結合する操作である のUNIONを使った構文が最も適切です。UNIONは列数・型・順序が一致するSELECT同士を結合し、結果を1つの集合として返します。本問では第1期と第2期を別々のSELECTで取り出し、それらを結合することで期待する6行(各部門につき2行)を得られます。
(補足)与えられたデータに重複行は存在しないため、実行結果はUNIONとUNION ALLで同一になります。重複を明示的に残したい場合はUNION ALL、重複を排除したい場合はUNIONを使います。

解法ステップ

  1. 問題が「列を行に変換」する(ワイド→ロング)であると把握する。
  2. 第1期分を部門コード・'期'ラベル・第1期売上の列順でSELECTする。
  3. 第2期分も同様の列順・型でSELECTする('期'ラベルは'第2期')。
  4. 2つのSELECTをUNION(または必要に応じてUNION ALL)で結合する。
  5. 最後にORDER BYで部門コード・期の順に整列する。
正答に相当するSQL(選択肢と同等の構文)は次の通りです。
SELECT 部門コード, '第1期' AS 期, 第1期売上 AS 売上
  FROM 部門別売上
UNION
SELECT 部門コード, '第2期' AS 期, 第2期売上 AS 売上
  FROM 部門別売上
ORDER BY 部門コード, 期;

選択肢別の誤答解説

  • ア(INTERSECT を使用)
    INTERSECTは2つのSELECTの「全列の値が完全に一致する行のみ」戻します。本問では同じ部門でも'期'列が'第1期'と'第2期'で異なるため、完全一致する行は存在せず、結果は空になります。よって不適切です。
  • ウ(CROSS JOIN を使用)
    CROSS JOIN は直積(Cartesian product)を生成します。元テーブルが3行ずつなら、3×3=9行となり、選択列がA側の値のみを参照しているため同じ行が複数回現れる(重複)ことになります。問合せ結果の意図である「各部門につき第1期と第2期をそれぞれ1行ずつ」の構成にはならず誤りです。
  • エ(INNER JOIN を使用)
    INNER JOIN で部門コードを結合すると部門ごとに対応する行がマッチしますが、選択している列がA(第1期)のみであるため、結果は第1期の行だけ(各部門1行)になり、第2期の行が出力されません。したがって問合せ結果と合致しません。

よくある誤解

  1. UNIONは必ず重複排除が必要だと思い込みUNION ALLを避ける
    • 実際にはUNIONは重複を排除し、UNION ALLは重複を保持します。データに重複がなければ結果は同じです。パフォーマンス面ではUNION ALLの方が高速な場合が多いので、重複があり得ない(または許容する)ならUNION ALLを選ぶ判断もあります。
  2. INTERSECTは「キーだけ一致すればよい」と考える誤解
    • INTERSECTはSELECTの全列の値が一致する行を返します。キー列だけ一致してもその他の列(本問では'期')が異なれば一致行にはなりません。
  3. JOINで列向け変換ができると思い込むミス
    • JOIN(INNER/CROSS等)は行同士の組合せを作るため、列を行に変換する目的には不適切な設計になることが多いです。単純なワイド→ロング変換ならUNION(またはDBMSのUNPIVOT機能)を使うのが明快です。

補足コラム

  • DBMSによってはUNPIVOT句やクロス適用(CROSS APPLY / LATERAL)など、列を行へ変換するための専用構文があります(例:OracleのUNPIVOT、SQL ServerのUNPIVOTやCROSS APPLY + VALUES)。これらは記述が簡潔になり性能上も有利な場合がありますが、試験問題では汎用的に使えるUNION/UNION ALLで解けるケースが多いです。
  • ORDER BYについて:UNIONを使う場合、ORDER BYは全体の結果に適用されます。列名の曖昧さを避けるためにはSELECTで付けたエイリアス(ここでは期、売上)を使うと読みやすいです。

FAQ

Q1. UNIONとUNION ALLのどちらを常に使うべきですか?
A1. 重複を排除したい場合はUNION、重複をそのままにしたいか性能重視ならUNION ALLを使います。今回のように元データに重複がないと分かっている場合はUNION ALLでも結果は同じです。
Q2. INTERSECTやEXCEPTはよく使いますか?
A2. 使いどころはありますが、列全体の一致に依存すること、DBMSによってはサポートが限られることに注意してください。集合演算は行集合の比較に便利です。
Q3. 「期」の順序が意図した通りにならない場合は?
A3. 文字列ソートの結果が想定と違うときは、ソートキーを付け(例:期番号カラムやCASE式で順序を数値化)てORDER BYに使うと確実に期待順で並べられます。

関連キーワード: SQL、UNION ALL、INTERSECT、UNPIVOT、ワイドからロング変換、CROSS JOIN、INNER JOIN、ORDER BY、列の正規化
← 前の問題へこの年度をクイズで解く次の問題へ →
戦国ITクイズ機能

\ せっかくなら /

応用情報技術者
クイズ形式で学習しませんか?

クイズ画面へ遷移する

すぐに利用可能!

©︎2026 情報処理技術者試験対策アプリ

このサイトについてブログプライバシーポリシー利用規約特商法表記開発者について