基本情報技術者 2013年 秋期 午後 問02
選手情報を管理する関係データベースの設計及び運用に関する次の記述を読んで、設問1〜4に答えよ。
ある少年野球リーグの事務局では、登録選手の氏名や成績などの個人情報を管理するために、関係データベースを構築することにした。このリーグには、近隣の8チームが参加している。
まず、リーグに所属するチームと登録選手の情報を管理するために、図1に示すチーム表と選手表を設計した。下線付きの項目は、主キーを表す。
設問1:
問題文を見る チームの対戦成績を管理する表を設計する。次の記述中のに入れる適切な答えを、解答群の中から選べ。
このリーグでは、毎年4月から翌年の3月までを1シーズンとし、試合は各チームが他のチームの全てと1回だけ対戦する総当たり方式で行う。
このデータベースでは、各チームの対戦成績や、勝利投手、敗戦投手などの情報を管理する。チーム成績は勝点によって順位付けする。勝点は、勝利チームに3点、敗戦チームに0点、引分けの場合は両チームに1点ずつを付与する。
最初、図1に示すチーム表に、必要な項目を追加することを考えたが、総当たりで対戦することから、表に繰返し項目が発生することになる。これを改善するために、aした。また、管理する情報の性質上、チーム表や選手表は更新しながら継続的に使用するが、対戦成績はシーズンごとに表を作成して管理したい。さらに、勝利投手や敗戦投手といった、個々の試合に関する情報を管理するには、別の表にした方が扱いやすいと判断して、図2に示す日程表と結果表を作成することにした。ここで、1シーズンで作成される結果表のレコード件数は、b件になる。

aに関する解答群
ア:インデックスを設定
イ:第1正規化
ウ:第2正規化
エ:第3正規化
オ:セキュリティを強化
bに関する解答群
ア:48
イ:56
ウ:64
エ:98
オ:112
カ:128
模範解答
a:イ、b:イ
解説
解答の導き方
a:繰返し項目をなくすための表の分け方を考えます。
問題文には、チーム表に対戦成績を追加すると「表に繰返し項目が発生する」とあります。総当たり方式では、各チームが他の7チームと対戦します。そのため、チーム表に対戦相手や得点などを直接追加すると、相手ごとに同じ種類の項目を繰り返し用意することになります。
このように、同じ種類の項目が何組も並ぶ状態を改善し、必要な情報を行として管理できるようにするのが第1正規化です。第1正規化では、1つの項目に同じ種類の情報を繰り返し持たせないようにします。
図2のように、試合の日程は日程表に、試合の結果は結果表に分けて管理すれば、対戦ごとに行を追加できます。したがって、aには第1正規化が入ります。
b:結果表のレコード(表の1行)の件数を求めます。
まず、1シーズンに行われる試合数を求めます。8チームのうち、対戦する2チームの組合せは次のとおりです。
では、各チームから見た対戦相手を数えるため、同じ試合を両方のチームから数えています。そのため、2で割って試合数を求めます。
次に、結果表の行数を考えます。図2では、同じ試合番号について、対戦した2チームそれぞれの行があります。つまり、1試合につき結果表には2件のレコードが必要です。
よって、1シーズンで作成される結果表のレコード件数は56件です。
誤りやすいポイント
- 試合数と結果表のレコード件数を混同しないようにします。 試合数は28試合ですが、結果表には1試合につき2チーム分の行があるため、レコード件数は56件です。
- をそのまま試合数と考えると、同じ対戦を2回数えてしまいます。試合数を求めるときは2で割ります。
- 繰返し項目をなくすための選択肢は第1正規化です。インデックスの設定やセキュリティの強化は、表の項目の繰返しを解消する方法ではありません。
FAQ
Q: なぜ結果表には、同じ試合番号の行が2件あるのですか?
A: 1試合には対戦するチームが2つあり、結果表では各チームの得点や勝点などをそれぞれ記録するためです。
A: 1試合には対戦するチームが2つあり、結果表では各チームの得点や勝点などをそれぞれ記録するためです。
Q: と計算して、結果表の件数を求めてもよいですか?
A: 求められます。各チームが他の7チームと対戦するため、チームごとの試合結果は件です。これは、1試合につき2チーム分の行を記録する数え方と同じです。
A: 求められます。各チームが他の7チームと対戦するため、チームごとの試合結果は件です。これは、1試合につき2チーム分の行を記録する数え方と同じです。
Q: 第1正規化では、何を改善するのですか?
A: 同じ種類の情報を列に何度も繰り返して並べるのではなく、1件ずつ行として追加できる形にします。この問題では、対戦情報をチーム表に繰り返し持たせず、日程表や結果表に分けています。
A: 同じ種類の情報を列に何度も繰り返して並べるのではなく、1件ずつ行として追加できる形にします。この問題では、対戦情報をチーム表に繰り返し持たせず、日程表や結果表に分けています。
関連キーワード: 関係データベース、主キー、第1正規化、繰返し項目、レコード
設問2:
問題文を見る 勝点が多いチームから降順にチーム番号、チーム名、勝点、総得点を表示する。
このとき、勝点が等しい場合は、総得点の降順に表示する。次のSQL文のに入れる正しい答えを、解答群の中から選べ。
SELECT チーム表.チーム番号, チーム表.チーム名,
SUM(結果表.勝点) AS 勝点, SUM(結果表.得点) AS 総得点
FROM チーム表, 結果表
WHERE チーム表.チーム番号 = 結果表.チーム番号
c
解答群
ア:GROUP BY チーム表.チーム番号, チーム表.チーム名 ORDER BY 勝点 ASC, 総得点 ASC
イ:GROUP BY チーム表.チーム番号, チーム表.チーム名 ORDER BY 勝点 DESC, 総得点 DESC
ウ:ORDER BY 勝点, 総得点 ASC
エ:ORDER BY 勝点, 総得点 DESC
模範解答
c:イ
解説
解答の導き方
この設問では、各チームの勝点と総得点を合計し、その合計値の順に並べる方法を考えます。SQL(Structured Query Language:データベースに問い合わせたり、データを操作したりするための言語)の中で、合計と並べ替えをどのように指定するかがポイントです。
-
チームごとに勝点と得点を合計します。
SELECT句では、集約関数(複数の行の値をまとめて計算する機能)SUMを使い、勝点と得点をそれぞれ合計しています。ASは、計算結果に名前を付ける指定です。ここでは合計結果に「勝点」と「総得点」という名前を付けています。 -
チームごとに集計するため、GROUP BYを指定します。
結果表には、試合ごとにチームの得点や勝点が記録されています。そのため、同じチームの行をまとめて合計する必要があります。
また、SELECT句ではチーム番号とチーム名も表示します。SUMのように合計する項目以外は、どの単位で集計するのかをGROUP BYに指定します。したがって、チーム番号とチーム名の両方が必要です。 -
勝点と総得点の両方を降順で並べます。
問題文には「勝点が多いチームから降順」とあります。さらに、勝点が同じ場合は「総得点の降順」とあります。つまり、まず勝点を大きい順に並べ、勝点が同じチーム同士は総得点の大きい順に並べます。
ORDER BYは並べ替えを指定する句で、DESCは降順を表します。よって、ORDER BYには勝点、総得点の順で指定し、どちらにもDESCを付けます。
以上より、GROUP BYでチームごとに集計し、ORDER BYで勝点と総得点をそれぞれ降順にするイが適切です。
誤りやすいポイント
-
GROUP BYとORDER BYの役割を混同する
GROUP BYは、どの単位でデータをまとめて集計するかを指定します。ORDER BYは、集計した結果をどの順番で表示するかを指定します。 -
SELECT句にあるチーム番号とチーム名をGROUP BYに含めない
チームごとの結果を表示するには、チーム番号とチーム名を集計の単位として指定します。どちらかを省くと、チームごとの集計になりません。 -
ASCとDESCを取り違える
ASCは昇順、DESCは降順です。問題文は勝点と総得点の両方について降順を指定しているため、どちらにもDESCが必要です。アはASCなので、並び順が問題文と逆になります。 -
GROUP BYを省いた選択肢を選ぶ
ウとエにはGROUP BYがありません。チームごとの合計を出すための指定が足りません。
FAQ
Q: 勝点が同じチームがあった場合、どの順に表示されますか?
A: その場合は、総得点が多いチームから表示されます。勝点を先に並べ、同じ勝点の中で総得点を並べるためです。
A: その場合は、総得点が多いチームから表示されます。勝点を先に並べ、同じ勝点の中で総得点を並べるためです。
Q: DESCを一つだけ指定すれば、勝点と総得点の両方が降順になりますか?
A: なりません。並べ替える項目ごとに順序を指定します。この設問では、勝点と総得点の両方にDESCを付けます。
A: なりません。並べ替える項目ごとに順序を指定します。この設問では、勝点と総得点の両方にDESCを付けます。
Q: GROUP BYにチーム番号とチーム名の両方を指定するのはなぜですか?
A: SELECT句で、合計値だけでなくチーム番号とチーム名も表示するためです。チームごとに集計した結果を表示できるよう、両方を集計単位として指定します。
A: SELECT句で、合計値だけでなくチーム番号とチーム名も表示するためです。チームごとに集計した結果を表示できるよう、両方を集計単位として指定します。
関連キーワード: GROUP BY、ORDER BY、集約関数、降順、列別名
設問3:
問題文を見る 選手個人の打撃成績を管理するために、図3に示す打席表と打撃表を作成した。
ホームランを打った数(以下、ホームラン数という)が多い選手から降順に選手番号、選手名、ホームラン数を表示する。次のSQL文のに入れる正しい答えを、解答群の中から選べ。ただし、d1とd2に入れる答えは、dに関する解答群の中から組合せとして正しいものを選ぶものとする。
SELECT 打席表.打者, 選手表.氏名, d1 AS 集計数
FROM 打席表, 選手表
WHERE 打席表.打者 = 選手表.選手番号 AND
打席表.打撃結果 = (SELECT 打撃表.打撃結果 FROM 打撃表 WHERE 打撃表.名称 = 'ホームラン')
GROUP BY 打席表.打者, 選手表.氏名
ORDER BY 集計数 d2

dに関する解答群


模範解答
d:ア
解説
解答の導き方
この設問では、選手ごとのホームラン数を数え、その数が多い順に表示するためのSQL(Structured Query Language:関係データベースに指示を出す言語)の空欄を考えます。
-
ホームランの打席だけに絞ります。
WHERE句では、打席表.打撃結果を「ホームラン」に対応する打撃結果と照合しています。つまり、この条件を通るのはホームランを打った打席の行だけです。図3の打席表は打席ごとの記録なので、条件に合う行を数えれば、選手ごとのホームラン数になります。 -
打席の記録と選手名を結び付けます。
「打席表.打者 = 選手表.選手番号」という条件で、打席表の打者番号と選手表の選手番号を一致させています。これにより、打者番号だけでなく選手名も表示できます。 -
選手ごとにホームランの行数を数えます。
GROUP BY句は、同じ打者と氏名の行をひとまとめにする指定です。集計関数(複数の行をまとめて数えたり、合計したりする機能)のCOUNT()は、まとまりの中にある行数を数えます。ホームランの行だけに絞った後で数えるため、選手ごとのホームラン数になります。したがって、d1にはCOUNT()が入ります。 -
ホームラン数が多い順に並べます。
問題文は「ホームラン数が多い選手から降順」と指定しています。降順は大きい値から小さい値へ並べることなので、d2にはDESCが入ります。
この組合せは解答群のアです。MAX(打席表.打者)やMIN(打席表.投手)は番号の最大値・最小値を求めるもので、ホームラン数にはなりません。また、SUM(打席表.打点)は打点の合計であり、ホームランの本数とは別の値です。
誤りやすいポイント
- COUNT(*)は、条件に合った行の数を数えます。ここではホームランの打席だけが対象なので、ホームラン数になります。
- 打点の合計とホームラン数は同じではありません。打点は、得点に結び付いた人数分の記録です。
- DESCは大きい値から小さい値への並び順です。少ない順にするASCとは逆です。
- GROUP BY句で選手ごとにまとめる前に、WHERE句でホームラン以外の打席を除いています。絞り込みと集計の順を取り違えないようにしましょう。
FAQ
Q: ホームランを打っていない選手も、ホームラン数0として表示されますか?
A: このSQLでは表示されません。WHERE句でホームランの打席だけを残してから集計するため、対象となる打席がない選手は結果に含まれません。
A: このSQLでは表示されません。WHERE句でホームランの打席だけを残してから集計するため、対象となる打席がない選手は結果に含まれません。
Q: COUNT(*)ではなくSUM(打席表.打点)を使うと、なぜホームラン数にならないのですか?
A: SUM(打席表.打点)は打点を合計します。ホームランの本数ではなく、ホームランによって記録された打点の合計を求めることになります。
A: SUM(打席表.打点)は打点を合計します。ホームランの本数ではなく、ホームランによって記録された打点の合計を求めることになります。
Q: DESCとASCは、どちらが多い順ですか?
A: DESCが多い値から少ない値への順です。ASCは少ない値から多い値への順です。
A: DESCが多い値から少ない値への順です。ASCは少ない値から多い値への順です。
関連キーワード: SQL、集約関数、GROUP BY、ORDER BY、降順
設問4:
問題文を見る このリーグでは、チーム表や選手表は更新しながら継続的に使用する。対戦成績と打撃成績はシーズンごとに表を作成するが、過去の情報も参照できるように、シーズン終了後も蓄積しておく。
リーグに所属する選手情報の管理について、次の記述中のに入れる適切な答えを、解答群の中から選べ。
新しい選手の情報は、選手表に追加すればよい。リーグを離れる選手の情報は、蓄積されている情報の参照を考慮して、削除せずに残しておいた方がよい。
ある選手がシーズン途中に別のチームへ移籍する場合、選手表のチーム番号を更新すると、例えば、SQL文を用いて当該シーズンにおけるeの集計はできなくなる。移籍前の情報は、抹消日を格納した上でそのまま残して、当該選手に新しい選手番号を割り振って登録する方法もあるが、その場合は、SQL文を用いてfの集計ができなくなる。そこで、このリーグでは、選手の移籍にも柔軟に対処できるように、選手の情報を図4に示すとおり所属選手表と選手表で管理するように変更した。ただし、移籍して元のチームに戻ることはないものとする。

解答群
ア:選手ごとのホームラン数
イ:チームごとの勝点
ウ:チームごとの総得点
エ:チームごとのホームラン数
オ:リーグの総得点
カ:リーグのホームラン数
模範解答
e:エ、f:ア
解説
解答の導き方
この問題では、移籍した選手の過去と現在の所属を記録できるか、また、その記録方法によってどの集計が難しくなるかを考えます。
-
選手表のチーム番号を更新する場合選手表のチーム番号を新しいチームの番号に書き換えると、選手表には現在の所属チームしか残りません。移籍前にどのチームに所属していたかは分からなくなります。打席表には、打者が選手番号で記録されています。ホームラン数をチーム別に集計するには、打席表の打者と選手表を、選手番号を手掛かりに対応させます。このように、共通する項目を使って複数の表の情報を組み合わせることを、表結合といいます。このとき、選手表から分かるチーム番号は現在の所属先です。そのため、移籍前に打ったホームランも、現在のチームのホームランとして数えられてしまいます。移籍前と移籍後を分けた、正確なチーム別の集計ができません。したがって、選手表のチーム番号を更新するとできなくなる集計は、チームごとのホームラン数です。選択肢ではエです。
-
移籍のたびに新しい選手番号を割り振る場合次に、移籍前の情報を残したまま、移籍後の情報には新しい選手番号を割り振る方法を考えます。この方法では、移籍前の打席記録には以前の選手番号が、移籍後の打席記録には新しい選手番号が残ります。データ上では別々の選手として扱われるため、同じ選手の移籍前と移籍後の記録を一人分としてまとめられません。その結果、選手ごとのホームラン数を正しく集計できなくなります。したがって、該当するのは選手ごとのホームラン数で、選択肢ではアです。
-
所属選手表を設ける場合そこで図4では、選手の情報とチームへの所属の情報を別々に管理しています。選手表の選手番号はそのままにし、所属選手表にチーム番号、選手番号、登録日、抹消日を記録します。図4では、選手番号0001について、チーム番号01に所属していた記録と、チーム番号03に所属している記録が別々に残っています。試合日と所属期間を照らし合わせれば、その試合時点での所属チームを判断できます。これにより、選手番号を変えずに選手ごとの成績をまとめながら、移籍前後の成績をチームごとにも分けて集計できます。SQL(Structured Query Language:データベースに問い合わせたり、データを操作したりするための言語)で集計するときも、試合日と所属期間を使えば、移籍の履歴を反映できます。
誤りやすいポイント
- 選手表のチーム番号を更新しても、選手の過去の試合記録は残ります。しかし、その記録をチーム別に分類するための過去の所属情報が失われるため、チームごとのホームラン数を正しく集計できません。
- 選手ごとの成績とチームごとの成績を混同しないようにしましょう。選手番号を変えない方法では、移籍前後の記録を同じ選手としてまとめられます。一方、チーム別に集計するには、試合当時の所属チームが必要です。
- 新しい選手番号を割り振れば移籍前の情報を残せますが、旧番号と新番号が同じ選手を指すという対応関係は、表から分かりません。そのため、選手単位の集計が難しくなります。
- 勝点や総得点は結果表にチーム番号とともに記録されています。選手表の所属情報を書き換えることによる影響と、選手の打席記録を使って求める集計とを区別しましょう。
FAQ
Q: 移籍前のホームランを、新しいチームのホームランとして数えてしまうのはなぜですか?
A: 打席表の打者を選手番号で選手表に対応させると、選手表に残っている現在のチーム番号が使われるためです。過去の所属期間が記録されていなければ、移籍前の打席記録も現在のチームに結び付いてしまいます。
A: 打席表の打者を選手番号で選手表に対応させると、選手表に残っている現在のチーム番号が使われるためです。過去の所属期間が記録されていなければ、移籍前の打席記録も現在のチームに結び付いてしまいます。
Q: 選手番号を変えなければ、チームごとのホームラン数も選手ごとのホームラン数も集計できますか?
A: 所属選手表に移籍の履歴があれば、選手番号を変えずに、選手ごとの記録をまとめられます。また、試合日と所属期間を照らし合わせれば、チームごとの記録にも分けられます。
A: 所属選手表に移籍の履歴があれば、選手番号を変えずに、選手ごとの記録をまとめられます。また、試合日と所属期間を照らし合わせれば、チームごとの記録にも分けられます。
Q: 「抹消日」がnullの場合は、どのように考えればよいですか?
A: その所属の終了日がまだ記録されていない状態です。選手が現在もそのチームに所属しているものとして扱えます。
A: その所属の終了日がまだ記録されていない状態です。選手が現在もそのチームに所属しているものとして扱えます。
関連キーワード: 関係データベース、主キー、表結合、SQL、データ集計




