MySQL8.0におけるGROUP集計・並び替え

#背景

ドットインストールの「MySQL入門」を進めていく中で
躓いた点があったので記事として残します。
同じように躓いた方の為に。

#開発環境

MacOS Mojave
MySQL 8.0.15

#内容

ドットインストールMySQL入門の
[\#22「group by, havingを使ってみよう」](https://dotinstall.com/lessons/basic_mysql_v3/40122)において、
事前にこのようなテーブルが作成されている状態からです。

```
+----+------------+-------+--------+
| id | name       | score | team   |
+----+------------+-------+--------+
|  1 | taguchi    |   5.8 | Team-C |
|  2 | fkoji      |   8.2 | Team-A |
|  3 | dotinstall |   6.1 | Team-B |
|  4 | Tanaka     |   4.2 | Team-C |
|  5 | yanada     |  NULL | Team-C |
|  6 | tashiro    |   7.9 | Team-B |
+----+------------+-------+--------+
```

この中からグループ分けをし、
かつ同じグループ同士の点数を足し合わせて表示するSQL文は
下記になります。

```sql

SELECT sum(score),team FROM users_with_team GROUP BY team;
```

出力結果は下記の通りです。

```
+-------------------+--------+
| sum(score)        | team   |
+-------------------+--------+
|                10 | Team-C |
| 8.199999809265137 | Team-A |
|                14 | Team-B |
+-------------------+--------+
```

この時点でドットインストールの動画と違う点は、
並び順がteam-A~Cになっていない所です。
おかしいな、と思いつつ次の内容に進みました。

次は、上で実施した内容を逆順にして表示します。

```sql
SELECT sum(score),team FROM users_with_team GROUP BY team DESC;
```

通常は"DESC"を付ければ問題ないはずですね。
出力結果を下記に示します。

```
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DESC' at line 1
```

まさかのエラーでしたが、恐らくMySQLの
ドットインストールで使用しているバージョンと
私の環境のバージョンが違っているので
こういうことがあるだろうなとは思っていました。

そこでMySQL8.0において
DESC関係の更新があったかどうか調査しましたが、
特にそれっぽい記事は見当たりませんでした。

仕方なく、英語が分からない私はおそるおそる、
最後の手段、スタックオーバーフローを覗きました。
そこにて気になる文がありました。

>SELECT * FROM db.table group by id order by id desc
>[スタックオーバーフローの記事より](https://stackoverflow.com/questions/53846308/group-by-desc-syntax-error-on-mysql-8-0-which-is-fine-on-5-7)

ドットインストールのSQL文は"GROUP BY"のみだったのに対し、
こちらは"ORDER BY"もついているではありませんか。

そこで、このスタックオーバーフロウの例文の通りにSQL文を修正してみました。

```sql
SELECT sum(score),team FROM users_with_team GROUP BY team ORDER BY team DESC;
```

出力結果を下記に示します。

```
+-------------------+--------+
| sum(score)        | team   |
+-------------------+--------+
|                10 | Team-C |
|                14 | Team-B |
| 8.199999809265137 | Team-A |
+-------------------+--------+
```

問題なく出力されましたね。

一体どういうことでしょうか。
基本に立ち返ってみましょう。

#GROUP BY

データベースでは、同じ内容が入っているレコードを
グループにすることができます。

グループとして扱うことで、
今回の目的であるグループごとの集計等、グループごとの処理が可能となります。

```sql

SELECT カラム名 FROM テーブル名 GROUP BY グループ化するカラム名;
```

#ORDER BY

レコードを指定したカラムの値の順番に表示させたい場合、
"ORDER BY"を使用します。

```sql

SELECT カラム名 FROM テーブル名 ORDER BY キーとなるカラム;
```

この状態では昇順で表示されます。
昇順を指定する場合は"ASC"、
降順を指定する場合は"DESC"を付けます。


・・・素人目線で考えて、
"ORDER BY"が付いてない状態で"DESC"が付いているのがおかしくね？

#分かったこと

じゃあ、なぜドットインストールは"GROUP BY"を説明する段階で
「昇順」「降順」の話を出したのか。

検索した中で具体的な記事は出てきませんでしたが、
おそらくMySQLの前のバージョン5.7では
"DESC"を使用する際は"ORDER BY"が省略できた為、
このように説明していたのではないかと考えられます。


この他にも、MySQL8.0になって変わった点、
追加された機能が多々あると聞いています。
既存の教育資料を使用する場合はバージョンに気をつけましょうね。

※私はこのような場合、出来るだけ最新バージョンを使用するようにしています。
　理由は、本番環境になった際、「このバージョンで勉強したから〜」といって
　古臭いバージョンに固執するエンジニアになりたくないからです。
　又、バージョンによる違いがあると、
　なぜ？どうして？を通して学べる点が多々あると思っています。
　淡々とサンプルコードを書き写す作業にならないので良いかと。

#参考資料

基礎からのMySQL 改訂版
[ドットインストール|MySQL入門#22](https://dotinstall.com/lessons/basic_mysql_v3/40122)