ホーム > データベーススペシャリスト試験 > 2024年
データベーススペシャリスト試験 2024年 午前2 問10
“従業員”表から, 男女それぞれの最年長従業員を除く全ての従業員を取り出すSQL文とするために, aに入れる字句はどれか。ここで, “従業員”表の構造は次のとおりであり, 実線の下線は主キーを表す。
従業員(従業員番号, 従業員名, 性別, 生年月日)
〔SQL文〕
SELECT 従業員番号, 従業員名 FROM 従業員 AS S1
WHERE 生年月日 > (a)
ア:
SELECT MIN(生年月日) FROM 従業員 AS S2
GROUP BY S2.性別
イ:
SELECT MIN(生年月日) FROM 従業員 AS S2
WHERE S1.生年月日 > S2.生年月日
OR S1.性別 = S2.性別
ウ:
SELECT MIN(生年月日) FROM 従業員 AS S2
WHERE S1.性別=S2.性別
(正解)エ:
SELECT MIN(生年月日) FROM 従業員
GROUP BY S2.性別
解説
# 問題の概要
“従業員”表には以下のカラムがあります。
| カラム名 | 説明 |
|------------|------------|
| 従業員番号 | 主キー |
| 従業員名 | 名前 |
| 性別 | 男性 or 女性 |
| 生年月日 | 従業員の生年月日(年齢を知るために使用) |
問題は、「男女それぞれの最年長従業員を除く全ての従業員を取得する」SQL文の一部(a)に入る字句を選ぶことです。
---
# 問題文のSQLの意味とポイント
```sql
SELECT 従業員番号, 従業員名 FROM 従業員 AS S1
WHERE 生年月日 > (a)
- ここでは表「従業員」を「S1」という別名で参照しています。
- 「a」に入る部分は、生年月日と比較するための値を返すサブクエリ(または式)でなければなりません。
- この条件で「生年月日 > (a)」という比較をしているため、(a)が性別ごとの最年長(もっとも古い生年月日)従業員の生年月日を示し、それより若い人だけを抽出する必要があります。
各選択肢の検討
- まず、最年長従業員とは「生年月日が最も小さい(古い)」従業員のことです。
- つまり、「性別ごとに最小の生年月日」を求め、これらの生年月日よりも「大きい(新しい)」生年月日の従業員だけを取得したいわけです。
ア
SELECT MIN(生年月日) FROM 従業員 AS S2 GROUP BY S2.性別
- GROUP BYで性別ごとの最小生年月日を複数行返します。
- しかし、
生年月日 > (a)
の部分に入れるには複数行は使えません。 - このままだとサブクエリは複数値を返しエラーになるため不適切。
イ
SELECT MIN(生年月日) FROM 従業員 AS S2
WHERE S1.生年月日 > S2.生年月日
OR S1.性別 = S2.性別
- S1は外側クエリの別名で、サブクエリ内で直接参照できない可能性がある。
- 条件の意味も不明瞭で、「S1.生年月日 > S2.生年月日 OR S1.性別 = S2.性別」は論理的に曖昧。
- 性別ごとの最小生年月日を求める目的として不適切。
ウ (正解)
SELECT MIN(生年月日) FROM 従業員 AS S2
WHERE S1.性別 = S2.性別
- サブクエリ内で、外側の行S1の性別と一致する性別の中から最小の生年月日を取得している。
- つまり、「この従業員の性別ごとに最年長の生年月日」を取得できる。
- したがって、
生年月日 > (a)
は、その従業員が所属する性別の最年長者の生年月日より新しい(若い)ことを意味し、「最年長者を除外」できる。
エ
SELECT MIN(生年月日) FROM 従業員 GROUP BY S2.性別
- S2という別名がこの文中にないのに使われており文法誤り。
- また、GROUP BYすると複数行返すので、比較対象として不適切。
まとめ
- 男女の性別ごとに最年長の生年月日を求める必要あり。
- そのために「WHERE S1.性別 = S2.性別」で性別を合わせ、生年月日の最小値を取得するのが正しい。
数式的理解
性別ごとに
を求め、その値よりも大きい(つまり、より生年月日が新しい)を条件とする(除外したいのはこの最小値にあたる最年長者)ことになる。
最終解答
- (a) に入る字句は
SELECT MIN(生年月日) FROM 従業員 AS S2 WHERE S1.性別 = S2.性別
- したがって選択肢「ウ」が正解です。