• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:SQLのGROUP BYについて)

SQLのGROUP BYについて

このQ&Aのポイント
  • SQLのGROUP BYについて解説します。
  • 従業員コードと従業員氏名をSELECT文に書く理由について説明します。
  • この問題の解答が正しいかどうかについての議論があります。

質問者が選んだベストアンサー

  • ベストアンサー
  • mitoneko
  • ベストアンサー率58% (469/798)
回答No.2

>SELECTに書く列名は、GROUP BYで指定された列名でなければならない  または、集計関数でなければならない。が必要ですね。  とまぁ、これはおいておいて・・・  group byで指定された列以外の列名がselect句に書かれたらどうなるかを考えてみましょう。  例えば、Y.勤務時間がselect句に書かれていたら・・・  当然、ある従業員のレコードを集めてきたら、勤務時間はいろいろな数字があるでしょう。どれを選べばいいのかは解りませんよね。  ですから、最初の規則があります。    この規則に従えば、示された解答は間違いです。  さて、ここからは、現実のシステムの実装の問題です。  規則に反したSQL文が入力された時に、エラーメッセージを出して処理を中断しなければならないという規則はありません。  つまり、ルール違反のSQLに対しては、システムは何をやってもOKです。  エラーメッセージを出すのもよし。でたらめな答えを出しても、それはそれでOKなんです。  このgroup byにおけるルール違反に対する一番簡単な実装は何か?group byで集計対象になったものの中から適当な任意のレコードの値をそのまま出してしまうことです(適当な任意のレコードの正体は多分、一番最初に扱ったレコードか一番最後に扱ったレコードです。)。  そして、この安直な実装をしているシステムは多いです。  さて、この安直な実装をしているシステムに、解答のSQL文を入れてみましょう。  ここで、問題文に書かれていない仮定をもうけます。従業員コードと、賃金テーブルの従業員区分はprimary key指定がされているものとします。(普通、この様なテーブルは・・・多分そうです。)  従業員コードはgroup by句に指定されていますから一意に決まります。  仮定から、従業員コードが一意に規定されると従業員区分も一意に定まります。よって、時間単価も一意に定まります。  さて、ここで時間単価が一意に定まったので、集計対象のどのレコードから時間単価を取ってこられても「害はありません。」同じ答えが出てきます。  このやり口をX.従業員氏名に適用すると、やはり同じ結論が出ます。  よって、group by句に指定すべき列名は、X.従業員コードのみとなります。  この安直な実装したシステムのselect文の文法を見ると、ちゃんとこれがマニュアルに明示してあるシステムもあります。  例えば、MYSQLのマニュアルだと、 --------------------------------------------------------------------------- MySQL は GROUP BY の使用を拡張し、GROUP BY 句には現れない SELECT リストでの、超集約カラムまたは計算の使用を可能にします。この機能を利用して、不要なカラムのソートやグループ分けを避けることで、性能を改善することができます。 (中略) GROUP BY 部から省略したカラムがグループ内で一定していない場合は、この機能を 使用しないで ください。サーバはいかなる値もグループから自由に戻すことができ、すべての値が同じでない限り、結果は不確定です。 ----------------------------------------------------------------------------  とちゃんとこのことが明示されています。  規格に準じるか、多数派に準じるか・・・いずれにせよ、中途半端な解答ですね。  あるシステムでは、明確に間違い(エラーメッセージではねられる)ですし、あるシステムでは正解だけれども効率が悪い。(group byに指定する列名が多くなれば、計算量が増えます。)  解答に対して抗議したい気分です。

hrt_shu
質問者

お礼

長文解答、ご親切にありがとうございました。 又の機会があれば、ご教授、よろしくお願いします。

すると、全ての回答が全文表示されます。

その他の回答 (1)

  • nda23
  • ベストアンサー率54% (777/1416)
回答No.1

Oracleっぽい書式ですね。 確かに、これだけ見ると間違っていますが、 賃金テーブルの従業員区分が唯一の一意 キーであれば、従業員:賃金は1:1の関係が 保証されます。従って、従業員コードが決ま れば、時間単価も一意に決まるので、集計 関数を使う必要はありません。1:nのn側には 集計関数を使う必要があります。 でも、ウルサイDBシステムだと文法エラーに なることがありますので、hrt_shu さんの見解は 正しいと言えます。 だから、その回答は「Oracleなら正解」というのが 本当のところです。

hrt_shu
質問者

お礼

親切な解答、ありがとうございます。 「1:nのn側には集計関数を使う必要」があるというのはとてもためになりました。 集計関数の問題が出された際に、より理解が深まる気がします。

すると、全ての回答が全文表示されます。

関連するQ&A