32995


**[マニュアル](https://dev.mysql.com/doc/refman/5.6/ja/group-by-
handling.html)を読む限り、MySQL の GROUP BY 拡張は、下記が必須条件のように(私には)読み取れました。**

> GROUP BY で名前が指定されていない各非集約カラム内のすべての値がグループごとに同じ

・内容が良く理解できないのですが、現実問題として「すべての値がグループごとに同じ」って状態はまずあり得ないのではないかと思います

* * *

**不確定な値を取得しても困るため、標準SQLで書きたいのですが** 、  
・例えば、リンク先のSQLを、標準SQLで書きたいという理由だけで下記へ変更した場合、SQLの意味は変わってくるでしょうか？  
・具体的には、「GROUP BY o.custid」と「GROUP BY o.custid, c.name」の相違点は？

[code]

    SELECT o.custid, c.name, MAX(o.payment)
      FROM orders AS o, customers AS c
      WHERE o.custid = c.custid
      GROUP BY o.custid, c.name;
    
[/code]

* * *

あるいは、下記SQLを標準SQLにしたい、という理由だけで

[code]

    SELECT o.custid, o.name,o,address,MAX(o.payment)
      FROM orders AS o
      GROUP BY o.custid;
    
[/code]

下記へ変更すると、意味は変わってくる？

[code]

    SELECT o.custid, o.name,o.age,o.sex,MAX(o.payment)
      FROM orders AS o
      GROUP BY o.custid, o.name, o.age, o.sex;
    
[/code]


CC BY-SA 3.0
2017-02-28T11:23:07.410
32994
2017-02-28T12:39:17.413
2017-02-28T12:35:13.837
7886
7886
question
mysql
MySQL での GROUP BY 処理で、標準SQLに沿うようにするため複数指定すると、結果は異なる？


「GROUP BY で名前が指定されていない各非集約カラム内のすべての値がグループごとに同じ」状況が、まさにそのページで例示されている以下のクエリです。

[code]

    SELECT o.custid, c.name, MAX(o.payment)
      FROM orders AS o, customers AS c
      WHERE o.custid = c.custid
      GROUP BY o.custid;
    
[/code]

customersの主キーはおそらくcustidでしょうから、

  1. GROUP BY o.custid により、グループごとに o.custid は一意
  2. WHERE o.custid = c.custid により、グループごとに c.custid は一意
  3. c.custid は customers の主キーなので、各グループに結合される customers は1行

となり、結合される customers の全ての列がグループ内で同じ値になることは自明です。

一方で、次のクエリの o.name や o.address はそのような保証はありません。

[code]

    SELECT o.custid, o.name, o.address,MAX(o.payment)
      FROM orders AS o
      GROUP BY o.custid;
    
[/code]

orders.custid は主キー制約やUNIQUE制約によって一意であることが保証されている列ではないでしょうから、custid
でグループ化したところで、グループ内に含まれている name や address
は様々であることが予想されます。この場合MySQLの拡張では、グループ内から適当に選択された値が取得されることになります。

ここで GROUP BY 句に name と address を指定した場合、それをグループ条件に追加するわけですから、異なる name や address
ごとに別のグループが作成されます。グループ分けが異なるのですから、MySQLの拡張を利用した場合とは異なる結果になる可能性があります。

ただし最初に挙げたクエリのように、実際にはグループ内の値が揃っているという場合であれば、その列をグループ条件に追加しても同じ結果が得られます。この場合に限ってはMySQLの拡張の代わりとして成立します。

* * *

もっとも、最初に説明した例は、ちょっと考えればグループ内で同じ値になることがわかるわけです。それぐらいDB側で考えてくれたっていいですよね。

そこでSQL99という規格では、このように「GROUP BY
の指定から（間接的にでも）値が一意に確定する列をSELECTに含められる」という仕様にしてもよいことになりました。MySQLでは5.7.5からこれをサポートしているため、冒頭のクエリは
**拡張を使わずとも** 有効です。

[code]

    SELECT o.custid, c.name, MAX(o.payment)
      FROM orders AS o, customers AS c
      WHERE o.custid = c.custid
      GROUP BY o.custid;
    
[/code]

また、これをサポートしたことで、「値が確定するかどうかに関わらず、GROUP
BYに指定していない列を指定できる」という拡張はデフォルトで無効になっています。

・・・という話が、[MySQL5.7のマニュアル](https://dev.mysql.com/doc/refman/5.7/en/group-by-
handling.html)に書かれています。英語ですが。


CC BY-SA 3.0
2017-02-28T12:39:17.413
32995
2017-02-28T12:39:17.413
8000
32994
answer