HOME»基本情報技術者試験掲示板»平成30年春期午後問3
投稿する
»[2962] 平成24年秋期午後問9 設問1のa, bに関して 投稿数:1
»[2961] CBT形式について 投稿数:5
平成30年春期午後問3 [2964]
Yuさん(No.1)
設問2でHAVING句で、グループ化列以外である「児童表.学年」を用いているためエラーになります。
とありますが、HAVING句でグループ化列を用いてはいけない理由は何でしょうか。
https://www.fe-siken.com/kakomon/30_haru/pm03.html
とありますが、HAVING句でグループ化列を用いてはいけない理由は何でしょうか。
https://www.fe-siken.com/kakomon/30_haru/pm03.html
2021.02.28 10:57
ありんこさん(No.2)
HAVING句でグループ化列を用いてはいけない理由は何でしょうか。
だと思うのでそのつもりで回答します。
GROUP BY 児童表.児童氏名 HAVING 児童表.学年=1
の
GROUP BY 児童表.児童氏名 をすると児童氏名ごとに纏めた情報を1レコードで返すので、
これは同姓同名の子供がいた場合1つのレコードとして扱うことになります。
その場合、田中太郎という子供が複数人(例として各学年に1人ずつの合計6人)いた場合に、
田中太郎で纏められた情報の1レコードの中の学年のカラムの中には1,2,3,4,5,6という6つの学年の情報があります。
上記の場合に HAVING 児童表.学年=1 を呼び出すと、児童表.学年は複数のデータを持っている為、SQL側ではどの値を返せば良いかわからないのでエラーが発生してしまいます。
なので、こういった複数のデータを持っている場合には、HAVING句では集計関数やグループ化列を用いた条件を記載します。
今回の場合だと、下記のような使い方です。(例として挙げただけなので、抽出条件に意味はないです。)
GROUP BY 児童表.児童氏名 HAVING 児童表.児童指名= 田中太郎
名前が田中太郎のレコードを返す。(複数人いればその情報がまとめられたレコードとして)
GROUP BY 児童表.児童氏名 HAVING MAX(児童表.学年)=6
名前でグルーピングして、それぞれの名前の生徒の中で6年生がいる名前のレコードを返す。
(名前が田中太郎という生徒の中に6年生がいれば、田中太郎全員の情報がまとめられたレコードを返す。)
仮に上記2パターンでGROUP BYを使用した場合も、問題文のSELECT句で、保護者表.保護者名となっており、
先ほどの説明と同様に、グルーピングした結果は複数の保護者の情報を持っているので、保護者表.保護者名を指定されたところで、どれを返せば良いのかわからないので同様にエラーが発生します。
GROUP BYを使用したら、HAVING句ではグループ化列か集計関数しか使用できない(実際にはグループ化した列と1対1の関係であれば問題ないはずです。)
SELECT句でも同様です。
だと思うのでそのつもりで回答します。
GROUP BY 児童表.児童氏名 HAVING 児童表.学年=1
の
GROUP BY 児童表.児童氏名 をすると児童氏名ごとに纏めた情報を1レコードで返すので、
これは同姓同名の子供がいた場合1つのレコードとして扱うことになります。
その場合、田中太郎という子供が複数人(例として各学年に1人ずつの合計6人)いた場合に、
田中太郎で纏められた情報の1レコードの中の学年のカラムの中には1,2,3,4,5,6という6つの学年の情報があります。
上記の場合に HAVING 児童表.学年=1 を呼び出すと、児童表.学年は複数のデータを持っている為、SQL側ではどの値を返せば良いかわからないのでエラーが発生してしまいます。
なので、こういった複数のデータを持っている場合には、HAVING句では集計関数やグループ化列を用いた条件を記載します。
今回の場合だと、下記のような使い方です。(例として挙げただけなので、抽出条件に意味はないです。)
GROUP BY 児童表.児童氏名 HAVING 児童表.児童指名= 田中太郎
名前が田中太郎のレコードを返す。(複数人いればその情報がまとめられたレコードとして)
GROUP BY 児童表.児童氏名 HAVING MAX(児童表.学年)=6
名前でグルーピングして、それぞれの名前の生徒の中で6年生がいる名前のレコードを返す。
(名前が田中太郎という生徒の中に6年生がいれば、田中太郎全員の情報がまとめられたレコードを返す。)
仮に上記2パターンでGROUP BYを使用した場合も、問題文のSELECT句で、保護者表.保護者名となっており、
先ほどの説明と同様に、グルーピングした結果は複数の保護者の情報を持っているので、保護者表.保護者名を指定されたところで、どれを返せば良いのかわからないので同様にエラーが発生します。
GROUP BYを使用したら、HAVING句ではグループ化列か集計関数しか使用できない(実際にはグループ化した列と1対1の関係であれば問題ないはずです。)
SELECT句でも同様です。
2021.03.02 12:26
ありんこさん(No.3)
HAVING句でグループ化列を用いてはいけない理由は何でしょうか。
ではなく
HAVING句でグループ化列以外を用いてはいけない理由は何でしょうか。
でした。
ではなく
HAVING句でグループ化列以外を用いてはいけない理由は何でしょうか。
でした。
2021.03.02 12:27
かなさん(No.4)
★FE ブロンズマイスター
一言で言ってしまうと、「SQL の仕様がそうなっているから」でしょうか。グループ化されていない列の比較演算等は where 句ですることになっているので、基本的にはそういう仕様で不都合は生じません。
MySQL という RDBMS のマニュアル(dev.mysql.com/doc/refman/5.6/ja/group-by-handling.html)にも、
と書かれています。
参考までに、先ほど紹介した MySQL では、「標準 SQL」を拡張させることができ、この場合は、having 句中で非集約列を参照することができます。この場合、ありんこさんがおっしゃっている「SQL側ではどの値を返せば良いかわからないのでエラーが発生してしまいます」という問題は、「どれか適当な行の値を返す」ことで対処します。
MySQL という RDBMS のマニュアル(dev.mysql.com/doc/refman/5.6/ja/group-by-handling.html)にも、
>標準 SQL では、GROUP BY 句を含むクエリーは、GROUP BY 句で名前が指定されていない HAVING 句の非集約カラムを参照できません。
と書かれています。
参考までに、先ほど紹介した MySQL では、「標準 SQL」を拡張させることができ、この場合は、having 句中で非集約列を参照することができます。この場合、ありんこさんがおっしゃっている「SQL側ではどの値を返せば良いかわからないのでエラーが発生してしまいます」という問題は、「どれか適当な行の値を返す」ことで対処します。
2021.03.03 10:42
その他のスレッド
»[2963] 令和元年秋期午後問13 【設問2】について 投稿数:3»[2962] 平成24年秋期午後問9 設問1のa, bに関して 投稿数:1
»[2961] CBT形式について 投稿数:5