平成27年午前2問11の解説について
shinjiroさん
(No.1)
解説がありませんが、わからないからでしょうか?
以下のような解説はいかがでしょうか?
観測テーブルに存在しないすべての(通番、鳥名)の組み合わせについて、観測数を0にしてレコードを新規追加するSQLを考える。
まず最初に(通番、鳥名)のすべての組み合わせ(当然だが、通番、鳥名は1行以上に記載があるものに限られる)を取得するために、観測テーブル同士の直積を得ることを考える。これは
SELECT DISTINCT obs1.通番、obs2.鳥名
FROM 観測 AS obs1、観測 AS obs2
によって得られる(重複をなくすためにDISTINCTは必要)。この結果のテーブルをT1とする。
この中から、観測テーブルにまだ存在しない(通番、鳥名)のすべての組み合わせをWHERE句によって絞り込む。
現在存在している(通番、鳥名)の組み合わせの一覧は観測テーブル(これをobs3とする)の射影によって得られるので、上記のT1の各行について、まだ存在していない(通番、鳥名)の組み合わせのみを抽出するために
WHERE NOT EXISTS ( SELECT * FROM 観測 AS obs3 WHERE obs1.通番=obs3.通番 AND obs2.鳥名=obs3.鳥名)
を記載する。
以上により
SELECT DISTINCT obs1.通番、obs2.鳥名
FROM 観測 AS obs1、観測 AS obs2
WHERE NOT EXISTS ( SELECT * FROM 観測 AS obs3 WHERE obs1.通番=obs3.通番 AND obs2.鳥名=obs3.鳥名)
により、それぞれの通番において観測されなかった鳥名の一覧が取得できる。
あとはこの結果を観測テーブルに観測数0でinsertすればよい。
なので、解答は ウ obs1.通番 = obs3.通番
となる。
以下のような解説はいかがでしょうか?
観測テーブルに存在しないすべての(通番、鳥名)の組み合わせについて、観測数を0にしてレコードを新規追加するSQLを考える。
まず最初に(通番、鳥名)のすべての組み合わせ(当然だが、通番、鳥名は1行以上に記載があるものに限られる)を取得するために、観測テーブル同士の直積を得ることを考える。これは
SELECT DISTINCT obs1.通番、obs2.鳥名
FROM 観測 AS obs1、観測 AS obs2
によって得られる(重複をなくすためにDISTINCTは必要)。この結果のテーブルをT1とする。
この中から、観測テーブルにまだ存在しない(通番、鳥名)のすべての組み合わせをWHERE句によって絞り込む。
現在存在している(通番、鳥名)の組み合わせの一覧は観測テーブル(これをobs3とする)の射影によって得られるので、上記のT1の各行について、まだ存在していない(通番、鳥名)の組み合わせのみを抽出するために
WHERE NOT EXISTS ( SELECT * FROM 観測 AS obs3 WHERE obs1.通番=obs3.通番 AND obs2.鳥名=obs3.鳥名)
を記載する。
以上により
SELECT DISTINCT obs1.通番、obs2.鳥名
FROM 観測 AS obs1、観測 AS obs2
WHERE NOT EXISTS ( SELECT * FROM 観測 AS obs3 WHERE obs1.通番=obs3.通番 AND obs2.鳥名=obs3.鳥名)
により、それぞれの通番において観測されなかった鳥名の一覧が取得できる。
あとはこの結果を観測テーブルに観測数0でinsertすればよい。
なので、解答は ウ obs1.通番 = obs3.通番
となる。
2018.01.26 22:14
shampooさん
(No.2)
参考書でこちらの問題を見て、解説を読んでも理解できずここにたどり着きました。
そもそも問題を正しく理解できていなかったのもありますが、shinjiroさんの解説 + sqlを実際に叩くことでやっと理解できました。
1回目の観測
ヒバリ1羽
メジロ3羽
2回目の観測
ヒバリ5羽
3回目の観測
メジロ3羽
カラス2羽
スズメ5羽
といった観測結果が観測テーブルに入っている。
ただし、このままだと観測数の平均値を正確にとれないため、一度でも確認できた鳥(例えばスズメ)は他の観測のときに来ていなかったとして、観測数を0にする。
つまり以下のようにしたい。
1回目の観測
ヒバリ1羽
メジロ3羽
カラス0羽
スズメ0羽
2回目の観測
ヒバリ5羽
メジロ0羽
カラス0羽
スズメ0羽
3回目の観測
ヒバリ0羽
メジロ3羽
カラス2羽
スズメ5羽
そのために直積とdistinctを使用し、鳥が来ていなかったとき(上記で0羽のとき)の通番と名前を取得している。
あとはWHERE句でもともと観測していた鳥を除くように指定している。
ということですよね?
そもそも問題を正しく理解できていなかったのもありますが、shinjiroさんの解説 + sqlを実際に叩くことでやっと理解できました。
1回目の観測
ヒバリ1羽
メジロ3羽
2回目の観測
ヒバリ5羽
3回目の観測
メジロ3羽
カラス2羽
スズメ5羽
といった観測結果が観測テーブルに入っている。
ただし、このままだと観測数の平均値を正確にとれないため、一度でも確認できた鳥(例えばスズメ)は他の観測のときに来ていなかったとして、観測数を0にする。
つまり以下のようにしたい。
1回目の観測
ヒバリ1羽
メジロ3羽
カラス0羽
スズメ0羽
2回目の観測
ヒバリ5羽
メジロ0羽
カラス0羽
スズメ0羽
3回目の観測
ヒバリ0羽
メジロ3羽
カラス2羽
スズメ5羽
そのために直積とdistinctを使用し、鳥が来ていなかったとき(上記で0羽のとき)の通番と名前を取得している。
あとはWHERE句でもともと観測していた鳥を除くように指定している。
ということですよね?
2018.01.27 14:01
shinjiroさん
(No.3)
>shampooさん
>そのために直積とdistinctを使用し、鳥が来ていなかったとき(上記で0羽のとき)の通番と名前を取得している。
直積とdistinctのみだと、得られるのはすべての通番と一回でも観測されたすべての鳥の組み合わせですね(内容は理解していると思うので、書き間違いでしょうか?)。その中から観測数0の組み合わせをWHERE句で選別するということです。
私は書籍ではなく、他のサイトでの解説を読んだのですが、さっぱり理解できなかったです。なので自分なりに考えてやっと理解できました。
もっとも、最初に問題を読んだときは、何がしたいのかすら理解できませんでしたが。
2018.01.27 17:56
shampooさん
(No.4)
>shinjiroさん
>直積とdistinctのみだと、得られるのはすべての通番と一回でも観測されたすべての鳥の組み合わせですね(内容は理解していると思うので、書き間違いでしょうか?)。その中から観測数0の組み合わせをWHERE句で選別するということです。
言葉の選択がよくなかったです、すみません。内容は理解できてるはずです!
私も何がしたいのか全然わかりませんでした。
そもそも通番を連番だと思い込んでいたり...
本当に助かりました。ありがとうございます。
2018.01.27 18:33
管理人
(No.5)
shinjiroさん
ご提案ありがとうございます。私自身も意味がわからず解説に苦慮していたため大変助かりました。shinjiroさんのご投稿をほぼそのまま使用させていただく形で、解説を作成いたしました。
間違い等ございましたら、ご指摘くだされば幸いです。
平成27年春期 午前Ⅱ 問11
http://www.db-siken.com/kakomon/27_haru/am2_11.html
ご提案ありがとうございます。私自身も意味がわからず解説に苦慮していたため大変助かりました。shinjiroさんのご投稿をほぼそのまま使用させていただく形で、解説を作成いたしました。
間違い等ございましたら、ご指摘くだされば幸いです。
平成27年春期 午前Ⅱ 問11
http://www.db-siken.com/kakomon/27_haru/am2_11.html
2018.01.29 18:07
shinjiroさん
(No.6)
ミルキー@管理人さん
確認しました。特に問題ないように思われます。採用していただき幸いです。まあ、解説に何か不備があっても、どこかの誰かが指摘してくれるでしょう。
確認しました。特に問題ないように思われます。採用していただき幸いです。まあ、解説に何か不備があっても、どこかの誰かが指摘してくれるでしょう。
2018.02.02 23:27
返信投稿用フォーム
スパム防止のためにスレッド作成日から30日経過したスレッドへの投稿はできません。