問11:前問と同じ「店舗テーブル」と「売上テーブル」に対し、次のSQL文(左外部結合)を実行した際に出力される結果の説明として、最も適切なものはどれか。 SELECT 店舗テーブル.店舗名, 売上テーブル.金額 FROM 店舗テーブル LEFT OUTER JOIN 売上テーブル ON 店舗テーブル.店舗ID = 売上テーブル.店舗ID;
- A:東京店が2行(金額:5000, 3000)、大阪店が1行(金額:8000)の、計3行のみが取得され、名古屋店は表示されない。
- B:東京店が2行(金額:5000, 3000)、大阪店が1行(金額:8000)、名古屋店が1行(金額:NULL)の、計4行が取得される。
- C:売上ID 104(店舗ID:4)のデータを含む、金額が記録されているすべての売上(計4行)が取得され、店舗名はすべて表示される。
- D:店舗テーブルと売上テーブルのすべての組み合わせである、計12行のクロス集計表が出力される。
- E:名古屋店(金額:NULL)と、店舗ID 4の売上(金額:2000、店舗名:NULL)の両方を含む、計5行が取得される。
【第11問:正解と解説】
正解:B
【解説】
・A:不適切:INNER JOINであれば名古屋店は除外されますが、LEFT OUTER JOINでは左側テーブル(店舗テーブル)の全行が保持されるため、名古屋店もNULLを伴って出力されます。
・B:適切:LEFT OUTER JOINでは、左側(FROM句の直後)にある「店舗テーブル」の全3店舗が必ず結果に残ります。売上がある東京店(2件)、大阪店(1件)はそのまま結合され、売上が一度もない「名古屋店」も、売上側の項目を「NULL」とした状態で1行残るため、合計4行(2+1+1)が出力されます。
・C:不適切:LEFT OUTER JOINは左側の店舗テーブルを基準にするため、右側の売上テーブルにしか存在しない店舗ID:4のデータ(売上ID:104)は出力されません。
・D:不適切:12行はCROSS JOIN(直積)の結果件数です。OUTER JOINは結合条件を基に行を対応付けます。
・E:不適切:LEFT OUTER JOINは左側テーブルが基準であるため、右側(売上テーブル)にのみ存在する店舗ID:4の行は出力されません。出力されるのは名古屋店(NULL)を含む左側テーブルの行だけです。
問12:SQLの「GROUP BY句」と「HAVING句」の組み合わせに関する記述として、最も適切なものはどれか。
- A:HAVING句は、GROUP BY句によるグループ化を行う「前」の段階で、各レコード(行)に対して個別に絞り込み条件を適用する句である。
- B:WHERE句の中にSUMやAVGなどの集計関数を直接記述してグループを絞り込むことはできないため、集計後の値に対する条件指定にはHAVING句を使用する。
- C:HAVING句を使用する場合、SQL文の中にGROUP BY句を記述することは文法上禁止されており、常にテーブル全体の集計に対してのみ機能する。
- D:HAVING句で指定できる条件カラムは、必ず主キーまたは外部キーとして定義されているインデックス付きの列に限定される。
- E:HAVING句はSELECT句よりも前に処理されるため、HAVING句の中で定義した「AS 略称」の別名をSELECT句の中で再利用することができる。
【第12問:正解と解説】
正解:B
【解説】
・A:不適切:グループ化を行う「前」に行の絞り込みを行うのは「WHERE句」の役割です。HAVING句はグループ化を行った「後」にグループ単位で絞り込みます。
・B:適切:SQLのルールとして、WHERE句の条件式に集計関数(SUM, AVG, COUNT等)を直接書くことはできません(例:WHERE SUM(売上) >= 10000 はエラー)。そのため、グループ集計された結果に対して「売上の合計が1万以上のグループ」という絞り込みを行うには、HAVING句(例:HAVING SUM(売上) >= 10000)を使用します。
・C:不適切:HAVING句はGROUP BY句と組み合わせて使用するのが原則であり、GROUP BY句の記述を禁止するルールは存在しません。GROUP BYなしのHAVINGはテーブル全体を1グループとして扱います。
・D:不適切:HAVING句の条件に使える列はインデックス付きのキー列に限定されるという制約はありません。集計関数の結果や一般の列を自由に条件として指定できます。
・E:不適切:SQLの処理順序はFROM→WHERE→GROUP BY→HAVING→SELECT→ORDER BYであり、HAVING句はSELECT句より前に処理されます。しかし、AS別名はSELECT句で定義されるため、一般にHAVING句内でSELECT句のAS別名を参照することはできません(一部DBMSで許容される拡張機能を除く)。
問13:次のSQL文を実行したとき、取得される「行数」として、正しいものはどれか。なお、対象の「顧客テーブル」には全部で10行のレコードがあり、そのうち「地区名」列が ‘東京’ の行が3行、 ‘大阪’ の行が2行、残り5行の地区名はすべて「NULL(空欄)」であるとする。 SELECT DISTINCT 地区名 FROM 顧客テーブル;
- A:3行
- B:2行
- C:4行
- D:10行
- E:0行(エラーになる)
【第13問:正解と解説】
正解:A
【解説】
・A:適切:DISTINCTキーワードは、検索結果から重複した値を取り除き、ユニークな値のみを1行ずつ出力します。「東京」「大阪」に加えて、値が空である「NULL」も独立した1つの状態(重複は排除される)として結果に1行出力されるため、合計3行が取得されます。
・B:不適切:NULLをカウントから除外して東京と大阪だけにした誤答です。DISTINCTはNULLも1つの種類として扱います。
・C:不適切:4行と答えた場合、NULLを複数の独立した値として誤ってカウントしています。NULLはDISTINCTにより1つの種類として扱われ、「東京」「大阪」「NULL」の合計3種類・3行のみが出力されます。
・D:不適切:10行と答えた場合はDISTINCTによる重複排除が機能していない想定であり、誤りです。DISTINCTはユニークな値のみを1行ずつ返します。
・E:不適切:DISTINCTはSQL構文として正しく動作します。NULLが含まれていてもエラーにはならず、NULLを1種類の値として1行出力します。
問14:SQLにおける「集計関数(COUNT、SUM、AVG)」と「NULL(空値)」の挙動に関する記述として、最も適切なものはどれか。
- A:COUNT(*) はNULLを含むテーブルの全行数をカウントするが、COUNT(列名) は指定した列の値がNULLである行を自動的に除外してカウントする。
- B:SUM(売上金額) を実行した際、列の中に1箇所でもNULLが含まれていると、足し算が行えず全体の合計結果も必ずエラーまたはNULLになる。
- C:AVG(点数) による平均値の計算では、NULLの行も「点数が0点である」とみなされ、全行数(NULLの行を含む数)で合計値を割って算出される。
- D:テーブルのすべての行の特定列がNULLであるとき、COUNT(列名) を実行すると、結果として「NULL」が返される。
- E:集計関数の中でNULLを正しく扱うためには、必ず事前にWHERE句で「列名 = NULL」という比較式を記述してNULLを明示的に集計対象に含める必要がある。
【第14問:正解と解説】
正解:A
【解説】
・A:適切:SQLの重要な仕様です。引数にアスタリスクを指定するCOUNT(*)は、行そのものの数を数えるためNULLの列があってもカウントされますが、特定の列名を指定するCOUNT(列名)は、その列がNULLの行を除外した数を返します。
・B:不適切:SUM関数はNULLを無視して合計を計算します。NULLが含まれていても他の数値の合計は正常に返されます。全行がNULLの場合のみ、結果としてNULLが返されます。
・C:不適切:AVG関数はNULLの行を完全に除外してから合計÷件数を計算します。NULLを0とみなしてカウントするという挙動は誤りです。
・D:不適切:COUNT(列名)でNULLの行がすべての行に及ぶ場合、結果として返されるのは「NULL」ではなく「0(ゼロ)」です。
・E:不適切:「列名 = NULL」という比較式はSQLでは常に評価不能(UNKNOWN)になります。NULLの存在確認には「IS NULL」演算子を使用します。また、集計関数はNULLを自動的に無視するため、事前に明示的に含める操作は不要です。
問15:次のSQL文(副問い合わせ・サブクエリ)と同等の結果を得られる、よりシンプルなSQL文の説明として、最も適切なものはどれか。 SELECT * FROM 社員 WHERE 部署コード IN (SELECT 部署コード FROM 部署 WHERE 地区 = ‘大阪’);
- A:社員テーブルの主キーをすべて部署テーブルの主キーに書き換える、データ更新(UPDATE)の文。
- B:社員テーブルから部署コードが ‘大阪’ という文字列に完全一致する行だけを抽出し、他テーブルとの結合を一切行わない単一のSQL文。
- C:社員テーブルと部署テーブルを左外部結合(LEFT OUTER JOIN)し、部署コードが一致しない「NULL」の行だけを抽出したSQL文。
- D:部署テーブルの全行に対して、社員テーブルの内容を縦に統合(UNION)し、地区が ‘大阪’ の行を排除したSQL文。
- E:社員テーブルと部署テーブルを「部署コード」で内部結合(INNER JOIN)し、WHERE句で部署テーブルの地区を ‘大阪’ に絞り込んだSQL文。
【第15問:正解と解説】
正解:E
【解説】
・A:不適切:元のSQL文はデータを参照(SELECT)するクエリであり、主キーの値を書き換えるUPDATE文とは全く異なります。
・B:不適切:「部署コードが’大阪’」という条件は意味をなしません。部署コードは部署を識別するコードであり、地区名とは別の項目です。他テーブルとの照合なしに社員テーブルのみで絞り込むことはできません。
・C:不適切:LEFT OUTER JOINはすべての社員を出力し、NULL行を「持つ」社員を抽出することになります。元のSQLは大阪の部署に属する社員を抽出するものであり、NULLを絞り込む処理とは異なります。
・D:不適切:UNIONは2つの検索結果を縦に統合する操作です。元のSQLは社員テーブルから条件に合致する行を絞り込む処理であり、縦統合とは全く異なります。
・E:適切:IN句を用いた副問い合わせ(サブクエリ)は、「大阪にある部署の、部署コード一覧」を内側で取得し、そのいずれかに該当する社員を外側で抽出しています。これは、社員テーブルと部署テーブルを部署コードで「内部結合(INNER JOIN)」し、条件を「地区 = ‘大阪’」とする操作と論理的に全く同じ(同値)結果を返します。

コメント