応用情報技術者 2019年 秋期 午後 問06
健康応援システムの構築に関する次の記述を読んで、設問1~3に答えよ。
W社は、ソフトウェアパッケージの開発を行う企業である。デスクワークが多いことから、従業員が生活習慣病に陥る比率が高く問題となっていた。そこでW社の人事部では、従業員の健康増進のために、通信機能をもつ体重計と、歩数や睡眠時間を記録するリストバンド型活動量計(以下、リストバンドという)を配布し、そのデータを活用する健康応援システム(以下、本システムという)を構築することになった。
〔本システムのシステム構成〕
本システムは、次の二つのサブシステムから構成される。
・健康応援データサービス
本システムのデータを管理するプログラム。各データを登録・更新・削除するためのインタフェースと定期的にデータを集計する機能をもつ。
・健康応援スマホアプリ
スマートフォン用のアプリケーションプログラム。体重計やリストバンドとデータ通信を行い、健康応援データサービスとデータ連携させる機能をもつ。
〔本システムの機能概要〕
本システムでは、従業員の日々の体重や歩数、睡眠時間などを記録して、その推移を可視化する。さらに、従業員間で記録を競わせるイベントを開催することで、従業員の積極的な利用を狙う。その機能概要は次のとおりである。
・手動データ登録機能
電子メールアドレスや身長をスマートフォンの画面から登録する。
・データ連携機能
体重計やリストバンドから取得したデータを登録する。
・データ公開機能
身長や体重などのそれぞれの情報について、自分以外の従業員にも閲覧を許可する場合、公開情報として設定する。
・月次レポート作成機能
毎月、従業員ごとの BMI(肥満度を表す体格指数)と肥満度判定、月間総歩数、平均睡眠時間を集計する。
・歩数対抗戦イベント
部署ごとの従業員一人当たり平均の月間総歩数を競う。
検討した健康応援データサービスで用いるデータベースの E-R 図を図1に示す。
このデータベースでは、E-R 図のエンティティ名を表名にし、属性名を列名にして、適切なデータ型で表定義した関係データベースによって、データを管理する。

〔月次レポート作成機能の実装〕
月次レポートを作成する処理手順を次に示す。
(1) 月次レポート表に従業員番号と集計する対象年月だけがセットされたレコードを挿入する。
(2) (1)で挿入したレコードについて、次の処理を行う。
① 身長と体重を、最新の測定値で更新する。
② BMIを算出して更新する。
③ BMIから肥満度を判定してその結果を更新する。
④ 対象年月の月間総歩数を集計して更新する。
⑤ 対象年月の睡眠時間を集計して1日当たりの平均睡眠時間を求め、その値で更新する。
処理手順(1)及び(2)④で用いるSQL文を、図2及び図3にそれぞれ示す。ここで、“:レポート年月”は、集計する対象年月を格納する埋込み変数である。
なお、関数COALESCE(A, B)は、AがNULLでないときはAを、AがNULLのときはBを返す。関数TOYMは、年月日を年月に変換する関数である。


〔データ連携機能の不具合〕
リストバンドに記録された睡眠データを用いてデータ連携機能のテストを行ったところ、睡眠データの登録処理でエラーが発生した。その際に用いたデータを図4に示す。
なお、この睡眠データはCSV形式で、先頭行はヘッダである。

まず、睡眠データの登録処理を確認したところ、その処理では、睡眠データの各行を順次取り出して、ヘッダと同名の睡眠表の各列に値をセットし、1行ずつ睡眠表に挿入していた。
次に、睡眠データを調査したところ、二つの想定外のパターンが判明した。
一つ目は、今回のエラーの原因ではなかったが、就寝中にリストバンドが外れてしまい睡眠終了日時が取得できないバターンで、このバターンに対応するために月次レポート作成機能を修正した。
二つ目が①今回のエラーを引き起こしたパターンで、このエラーを回避して全ての睡眠データを登録するために、②ある表に列の追加以外の変更を加え、月次レポート作成機能を修正することで、今回のエラーを解消することができた。
設問1:
図1中のa〜dに入れる適切なエンティティ間の関連及び属性名を答え、E-R図を完成させよ。
なお、エンティティ間の関連及び属性名の表記は、図1の凡例に倣うこと。
模範解答
a:→
b:部署番号
c:従業員番号
d:↓
解説
解答の論理構成
-
部署と従業員の関連
- 問題文には「部署ごとの従業員一人当たり平均の月間総歩数を競う。」とあります。部署が複数の従業員を束ねるモデルであることが分かり、1 対 多 の関連です。図1では実線+矢印で表記され、空欄 a には矢印記号そのものが入ります。
→ a:→
- 問題文には「部署ごとの従業員一人当たり平均の月間総歩数を競う。」とあります。部署が複数の従業員を束ねるモデルであることが分かり、1 対 多 の関連です。図1では実線+矢印で表記され、空欄 a には矢印記号そのものが入ります。
-
従業員表に必要な外部キー
- 部署と従業員が 1 対 多 なので、従業員表は部署を参照する外部キーを持ちます。部署側の主キーは「部署番号」ですから、空欄 b には同じく「部署番号」が入ります。
→ b:部署番号
- 部署と従業員が 1 対 多 なので、従業員表は部署を参照する外部キーを持ちます。部署側の主キーは「部署番号」ですから、空欄 b には同じく「部署番号」が入ります。
-
月次レポートと従業員の関係
- 月次レポートは「従業員ごと」の集計結果を保持すると問題文に明記されています。従って月次レポート表の主キーには従業員を識別する「従業員番号」が必須です。
→ c:従業員番号
- 月次レポートは「従業員ごと」の集計結果を保持すると問題文に明記されています。従って月次レポート表の主キーには従業員を識別する「従業員番号」が必須です。
-
従業員と公開の関連
- 従業員は公開設定を複数持てるため 1 対 多。図1では従業員側から公開側へ垂直方向の実線が描かれており、先端は下向き矢印で表されます。空欄 d には下向き矢印記号をそのまま記入します。
→ d:↓
- 従業員は公開設定を複数持てるため 1 対 多。図1では従業員側から公開側へ垂直方向の実線が描かれており、先端は下向き矢印で表されます。空欄 d には下向き矢印記号をそのまま記入します。
誤りやすいポイント
- 外部キーと主キーの混同
「従業員番号」を従業員表だけのものと決め付け、月次レポート表の主キーに含め忘れるケースが頻発します。 - 矢印記号の方向
「←」「→」「↓」などを関係名だと思い込み、実際の記号で解答しないミスが見られます。 - 部署番号の置き場所
部署表にしか部署番号が無いと誤解し、従業員表に外部キーを追加できないケースがあります。
FAQ
Q: 矢印そのものを答案に書くのですか?
A: はい。図1では記号自体がブランク指定されているため、→ や ↓ をそのまま解答します。
A: はい。図1では記号自体がブランク指定されているため、→ や ↓ をそのまま解答します。
Q: 「従業員番号」と「部署番号」は複合キーにすべきですか?
A: 本問題ではそれぞれ独立した主キーであり、複合キーにはしません。従業員表は「従業員番号」を、部署表は「部署番号」を単独主キーとしています。
A: 本問題ではそれぞれ独立した主キーであり、複合キーにはしません。従業員表は「従業員番号」を、部署表は「部署番号」を単独主キーとしています。
Q: 公開設定はなぜ多対多ではないのですか?
A: 一人の従業員が複数の公開情報を選択する構造なので 1 対 多 で十分です。公開表側に従業員番号が含まれることで多重度を担保します。
A: 一人の従業員が複数の公開情報を選択する構造なので 1 対 多 で十分です。公開表側に従業員番号が含まれることで多重度を担保します。
関連キーワード: ER図、主キー、外部キー、1対多、関係データベース
設問2:〔月次レポート作成機能の実装〕について、(1)、(2)に答えよ。
(1)図2中のeに入れる適切な字句又は式を答えよ。
模範解答
e:SELECT従業員番号、:レポート年月
解説
解答の論理構成
-
【問題文】では「(1) 月次レポート表に従業員番号と集計する対象年月だけがセットされたレコードを挿入する。」と指示しています。
-
図2の SQL 骨格はINSERT INTO 月次レポート(従業員番号、レポート年月) e FROM 従業員となっており、INSERT INTO の次に列名が並び、その直後に 従業員表から全従業員を取得しつつ、定数として “:レポート年月” を付加する SELECT 句 が必要です。
-
従業員表に存在する列は【問題文】中で「従業員番号」が示されています。集計対象年月は埋込み変数 “:レポート年月” と指定されています。
-
従って、e に入るのは
sql SELECT 従業員番号、:レポート年月となります。これにより「従業員番号」は動的に取得、「レポート年月」は全行で同一値を設定する要件を満たします。
誤りやすいポイント
- VALUES 句を使ってしまい、従業員数分のレコードを生成できない。
- SELECT 句で 従業員番号 しか指定せず、レポート年月 を忘れる。
- :レポート年月 にシングルクォートを付けて文字列リテラルと誤解する。
- FROM 句を 従業員 ではなく 月次レポート と書いてしまう転記ミス。
FAQ
Q: :レポート年月 にはどのような値がバインドされますか?
A: “YYYY-MM” 形式などシステムが採用する年月フォーマットで、集計対象の年月が実行時にバインドされます。
A: “YYYY-MM” 形式などシステムが採用する年月フォーマットで、集計対象の年月が実行時にバインドされます。
Q: 既に同じ従業員番号・レポート年月の行がある場合はどうなりますか?
A: 本問では INSERT 文のみ示されています。実運用では一意制約や MERGE 句などで重複挿入を防ぐ設計が望まれます。
A: 本問では INSERT 文のみ示されています。実運用では一意制約や MERGE 句などで重複挿入を防ぐ設計が望まれます。
Q: INSERT … SELECT 構文で列数が合わないとどうなりますか?
A: 列数またはデータ型が合わない場合、DBMS は構文エラーを返します。列順序にも注意が必要です。
A: 列数またはデータ型が合わない場合、DBMS は構文エラーを返します。列順序にも注意が必要です。
関連キーワード: INSERT-SELECT, 埋込み変数、一括挿入、定数列、サブクエリ
設問2:〔月次レポート作成機能の実装〕について、(1)、(2)に答えよ。
(2)図3中のf、gに入れる適切な字句又は式を答えよ。
模範解答
f:SUM(歩数、歩数)
g:歩数.従業員番号=月次レポート.従業員番号
解説
解答の論理構成
- 月次レポートに格納する「月間総歩数」は、対象年月の従業員ごとの歩数合計です。問題文には
“④ 対象年月の月間総歩数を集計して更新する。”
とあり、集計(合計)であることが明示されています。 - 図3の SQL 文は UPDATE 月次レポート SET 月間総歩数 = (SELECT … FROM 歩数 …) という形で、 サブクエリ側で歩数を集計し、その結果を COALESCE で NULL から “0” へ置き換えています。
- したがって f には「歩数列を合計する式」を入れる必要があります。表名と列名はいずれも同じ “歩数” なので、 SUM(歩数.歩数) が最適な表記となります。
- 次に g は、月次レポートの対象となる従業員を歩数表とひも付ける結合条件です。これは従業員番号で一致させる以外に選択肢がありません。
よって
歩数.従業員番号 = 月次レポート.従業員番号
が正しい条件になります。 - 以上より
• f:SUM(歩数.歩数)
• g:歩数.従業員番号 = 月次レポート.従業員番号
となります。
誤りやすいポイント
- 列名と表名が同じ「歩数」の二重指定を省略し、SUM(歩数) と書いてしまう
→ 別名を与えていないため曖昧さ回避のために完全修飾形 歩数.歩数 が必要です。 - 結合条件を忘れ、対象年月だけで抽出してしまう
→ 結合条件が無いと全従業員の歩数が合算され、従業員別の月間総歩数になりません。 - NULL 処理を忘れる
→ 対象月に歩数データがない従業員は NULL となり、演算結果が欠損します。COALESCE で0補完することが大切です。
FAQ
Q: SUM に DISTINCT を付ける必要はありませんか?
A: 歩数表には1従業員・1測定日につき1行が前提なので重複はなく、DISTINCT は不要です。
A: 歩数表には1従業員・1測定日につき1行が前提なので重複はなく、DISTINCT は不要です。
Q: 月間総歩数を別途ビューで計算しておく設計はダメですか?
A: 設計として問題ありませんが、本問は「サブクエリを用いた直接更新」という実装方針を示しているので、それに合わせる必要があります。
A: 設計として問題ありませんが、本問は「サブクエリを用いた直接更新」という実装方針を示しているので、それに合わせる必要があります。
Q: COALESCE ではなく NVL などでも良いですか?
A: 採点観点は「NULL を0に置き換える」ことです。NVL など同等機能を持つ関数でも正解になります。
A: 採点観点は「NULL を0に置き換える」ことです。NVL など同等機能を持つ関数でも正解になります。
関連キーワード: 集約関数、サブクエリ、内部結合、NULL処理、月次集計
設問3:〔データ連携機能の不具合〕について(1)、(2)に答えよ。
(1)本文中の下線①のパターンとは、どのような睡眠データのパターンか。30字以内で述べよ。
模範解答
1日に2回以上睡眠を取得するパターン
解説
解答の論理構成
-
【問題文】のE‐R図では、エンティティ“睡眠”の主キーが“従業員番号”と“測定日”であることが示されています。
→ 主キーは同一従業員について同一測定日が重複すると登録できません。 -
【問題文】図4の睡眠データを見ると、“EMP00001, 2019-10-04, …” が2行存在します。
→ 同じ従業員・同じ測定日で2行目を挿入しようとすると主キー制約違反が発生します。 -
本文中で「①今回のエラーを引き起こしたパターン」と記されているのは、この重複が原因で挿入エラーが発生したケースを指します。
-
したがって「1日に複数回睡眠を計測したときに、同じ“測定日”が重複して登録される」ことがエラー要因であり、模範解答である「1日に2回以上睡眠を取得するパターン」と整合します。
誤りやすいポイント
- “睡眠開始日時”と“睡眠終了日時”が異なれば主キーが違うと誤解し、重複チェックを見落とす。
- 主キー制約違反とNOT NULL違反を混同し、原因を NULL 値と判断してしまう。
- 就寝が跨日(例:22:30~翌06:30)なので“測定日”も跨いでいると勘違いし、1日2回計測という事実を読み取れない。
FAQ
Q: なぜ“測定日”を主キーにしたのですか?
A: 月次集計では1日に1度の睡眠時間を扱う設計方針だったため、従業員番号+測定日で一意とする想定でした。複数回睡眠がある場合は別設計が必要になります。
A: 月次集計では1日に1度の睡眠時間を扱う設計方針だったため、従業員番号+測定日で一意とする想定でした。複数回睡眠がある場合は別設計が必要になります。
Q: エラーを回避するにはどうすればよいですか?
A: “睡眠”表に連番など第三の主キー列を追加し、従業員番号+測定日で一意制約を外すか、アプリ側で同日データを結合してから1行にまとめて登録する方法があります。
A: “睡眠”表に連番など第三の主キー列を追加し、従業員番号+測定日で一意制約を外すか、アプリ側で同日データを結合してから1行にまとめて登録する方法があります。
Q: 月次レポート作成機能はどこを修正したのですか?
A: 同日複数行になることを考慮し、睡眠時間集計時に SUM や AVG を求めるサブクエリに GROUP BY 従業員番号、測定日 を追加するなど、重複行前提の集計ロジックへ変更しました。
A: 同日複数行になることを考慮し、睡眠時間集計時に SUM や AVG を求めるサブクエリに GROUP BY 従業員番号、測定日 を追加するなど、重複行前提の集計ロジックへ変更しました。
関連キーワード: 主キー制約、データ重複、集計ロジック、インポートエラー、正規化
設問3:〔データ連携機能の不具合〕について(1)、(2)に答えよ。
(2)本文中の下線②にある変更を加えた表の表名と、変更内容を答えよ。
なお、変更内容は、30字以内で述べよ。
模範解答
表名:睡眠
変更内容:主キーを“従業員番号、睡眠開始日時”に変更する。
解説
解答の論理構成
-
エラーの直接原因
- 図4には同一の“従業員番号”と“測定日”が重複している行がある。特に
“EMP00001, 2019-10-04, 2019-10-04 04:30:00, 2019-10-04 07:00:00” と
“EMP00001, 2019-10-04, 2019-10-04 23:45:00, 2019-10-05 06:45:00”
の2行は“測定日”が同じ“2019-10-04”である。
- 図4には同一の“従業員番号”と“測定日”が重複している行がある。特に
-
元の主キー仕様を確認
- 図1の“睡眠”エンティティでは主キーに“従業員番号、測定日”が下線付きで示されている。
- 従って、同一従業員が同一“測定日”で2行目を挿入すると主キー重複エラーが発生する。
-
問題文のヒント
- 下線①は「今回のエラーを引き起こしたパターン」、下線②は「ある表に列の追加以外の変更を加え」とある。
- 列を追加せずに重複を防ぐには主キー定義を変更するしかない。対象は“睡眠”表である。
-
主キーを何にするか
- “睡眠開始日時”は1レコードごとに固有で図4の6行すべてで重複していない。
- “従業員番号、睡眠開始日時”を主キーにすれば、同一従業員が1日に複数レコードを持っても一意性が保たれる。
-
結論
- 表名:「睡眠」
- 変更内容:「主キーを“従業員番号、睡眠開始日時”に変更する。」
誤りやすいポイント
- “測定日”を日付型のまま主キーに残すと、深夜勤務や複数睡眠などの実運用を取りこぼす。
- 列の追加(サロゲートキー追加など)と読み違えると設問条件「列の追加以外」に反する。
- “睡眠終了日時”を含めて主キーにすると、終了未取得レコード(NULL)の扱いで再び一意性が崩れる。
FAQ
Q: なぜ“睡眠開始日時”だけでなく“従業員番号”も主キーに含めるのですか?
A: 別の従業員が同じ日時に就寝するケースを区別するためです。一意性を保証するには両列が必要です。
A: 別の従業員が同じ日時に就寝するケースを区別するためです。一意性を保証するには両列が必要です。
Q: サロゲートキー(連番)を追加する方法では駄目なのですか?
A: 設問条件に「列の追加以外」とあるため、既存列の組合せで主キーを再定義する必要があります。
A: 設問条件に「列の追加以外」とあるため、既存列の組合せで主キーを再定義する必要があります。
Q: 主キーを変更した後、月次レポート作成機能に影響はありますか?
A: 集計は“従業員番号”と“測定日”を対象月で絞り込むため、主キー変更によるSQL修正は不要です。
A: 集計は“従業員番号”と“測定日”を対象月で絞り込むため、主キー変更によるSQL修正は不要です。
関連キーワード: 主キー制約、一意性違反、正規化、データインポート、参照整合性


