MySQLのGROUP BY句でエラーが出る原因と解決方法【基礎からのMySQL】

MySQLのGROUP BY句でエラーが出る原因と解決方法【基礎からのMySQL】




こんにちは。ネットショップコンサルタント「たぶ」(@yusuke_tanaka34)です。

今日は「MySQLのGROUP BY句でエラーが出る原因と解決方法」を解説していきます。

「MySQL」を独学で学習する上でいくつか書籍の候補があると思いますが、今回は「基礎からのMySQL 第3版」を使って学習することを前提に話を進めていきます。

独学で勉強していてつまづくことって多いですよね。僕も「基礎からのMySQL」を買って「MySQL」の勉強をしていたのですが、最初につまづいたのがこの「GROUP BY句」

たぶくん
例題どおりに打ち込んでるのに、なんでエラーが出るの!?

そうなんです。「基礎からのMySQL」に書いてある例題どおりにコマンドを打ち込んでも、エラーが出てしまうのです。

Google先生でいろいろ検索してみたのですが、どうもしっくり来る解決方法が見つからない。。。

なんとなくエラーが出る原因は分かるものの、できれば納得して次に進みたいですよね。

実は「GROUP BY」句でエラーが出る原因は、「MySQL」のバージョンアップによる仕様の変更なのです。

この記事を読めば「MySQLのGROUP BY句でエラーが出る原因と解決方法」が分かります。

簡単に言うと、「GROUP BYで指定したカラムをSELECTで選択する」んです。

一言で表現すると難しく感じますね…笑

それでは、「MySQLのGROUP BY句でエラーが出る原因と解決方法」をご紹介していきますね。




「GROUP BY」句とは

「GROUP BY」句とは

「GROUP BY」句とは、「データベースに入っているデータを呼び出す時にグループとしてまとめる」ためのコマンドです。

たとえば、このように学校の生徒名簿があったとします。

学校の生徒名簿(サンプル)

カラム「class」「GROUP BY」句を指定すれば、「1・2・3・4・5・・・」と各数字が入ったレコードをグループ化することができます。

同じ値が入ったレコードを「グループ」として扱うことで、各クラスの生徒数を数えたり、カラム「point」に入った点数の合計や平均などの集計をグループ単位で処理することができるようになるのです。

どのカラムを対象にグループ化するのかを指定するために「GROUP BY」句を使用します。

「GROUP BY」句の書き方は以下のとおり。

SELECT カラム名 FROM テーブル名 GROUP BY グループ化したいカラム名

これでカラムをグループ化して表示することができます。

「GROUP BY」句を使って出たエラー

「GROUP BY」句を使って出たエラー

今回、僕がつまづいたところは「基礎からのMySQL 第3版」のP.154

「グループごとに表示する」

SELECT * FROM tb GROUP BY bang;
引用:「基礎からのMySQL 第3版」P154

このコマンドを打ち込むと、

ERROR 1055 (42000): Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'db1.tb.uria' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

とエラーが出てしまいます。

エラーの内容を直訳してみると、

エラー1055(42000):SELECTリストの式#2がGROUP BY句に含まれず、GROUP BY句のカラムに機能的に依存していない非集約カラム ‘db1.tb.uria’が含まれています。これはsql_mode = only_full_group_byと互換性がありません。

とのこと。

要するに、『「GROUP BY」句を使っていると「*」で表示はできませんよ。「GROUP BY」句を使っている場合は、「SELECT」する時にカラム名をちゃんと書いてください。』という意味です。

また、「基礎からのMySQL 第3版」のP.215「自己結合」の「順位付けの妙技 その1」でも同じエラーが出てきます。

SELECT a.nama,a.tosi,COUNT(*)
 FROM tb1 AS a
JOIN tb1 AS b
 WHERE a.tosi<=b.tosi
GROUP BY a.bang;
引用:「基礎からのMySQL 第3版」P.216

こちらもエラーが出る原因は同じで、

GROUP BY a.bang;

『「bang」でグループにしろ。』って書いてあるけど、

SELECT a.nama,a.tosi,COUNT(*)

「SELECT」「bang」を選んでないやんけ。

ということです。




「GROUP BY」句がエラーになる原因

「GROUP BY」句がエラーになる原因

「GROUP BY」句がエラーになってしまう原因は、PHPの

sql_mode

「MySQL5.7」からMySQLの「ONLY_FULL_GROUP_BY」オプションが初期設定でONになったためです。

sql_mode=only_full_group_by

この「ONLY_FULL_GROUP_BY」オプションとは、『「GROUP BY」句を使う場合、きちんとSELECT部分にGROUP化するカラムを書き込みなさい。』というオプションです。

「基礎からのMySQL 第3版」では「MySQL5.6.34」を使用しているのですが、「MySQL5.6.34」では初期設定で「ONLY_FULL_GROUP_BY」オプションがONになっていませんでした。

これが原因で「GROUP BY」句がエラーになってしまうのです。

「GROUP BY」句のエラーを解決する方法

「GROUP BY」句がエラーになる原因

「GROUP BY」句のエラーを解決する方法は、「GROUP BYで指定したカラムをSELECTで選択する」だけです。

「*」「すべてのカラムを表示する」というコマンド。

「GROUB BY」句を使う時は「*」を使わず、カラム名を書き込むことで解決できます。

「基礎からのMySQL 第3版」のP.154の例で言うと、

SELECT bang FROM tb GROUP BY bang;

とコマンドを打ち込むことで、「A101」から「A107」の5種類のカラムが「bang」には存在することが分かります。

もともと「基礎からのMySQL 第3版」のP.154の例では、「グループに属しているレコードが勝手に選ばれた」と書いてあります。

「uria」「tuki」に入っている値はカラムの中の適当なものが入っているということです。

よって、

SELECT bang FROM tb GROUP BY bang;

でも、同じ結果が得られるということです。

「bang」に各データがいくつずつあるか知りたい場合は、

SELECT bang,COUNT(*) FROM tb GROUP BY bang;

で数えることができます。

次に「基礎からのMySQL 第3版」のP.215「自己結合」の「順位付けの妙技 その1」の例ですが、

SELECT 
  a.bang,a.nama,a.tosi,COUNT(*)
FROM tb1 AS a
  JOIN tb1 AS b
WHERE a.tosi<=b.tosi
  GROUP BY
a.bang,a.nama,a.tosi;

これで表示されます。

ただ、これだと順位がバラバラに表示されるので、

SELECT 
  a.bang,a.nama,a.tosi,COUNT(*)
FROM tb1 AS a
  JOIN tb1 AS b
WHERE a.tosi<=b.tosi
  GROUP BY
a.bang,a.nama,a.tosi
  ORDER BY COUNT(*);

とした方が見やすいかもしれませんね。

「GROUP BY エラー」で検索すると、「sql_mode」を変更する方法などが紹介されているのですが、サーバーによっては「sql_mode」を変更できないところもありますし、標準SQLでは不正になる書き方なので、長期的に考えるとあまりおすすめできません。

なので、「GROUP BYで指定したカラムをSELECTで選択する」を意識して、「GROUP BY」句の使い方をマスターするのがいいのかなと思います。




まとめ

今回は『MySQLのGROUP BY句でエラーが出る原因と解決方法』というテーマでお送りしてきました。

「GROUP BY」句のエラーは解決できましたでしょうか?

おさらいですが、「GROUP BY」句のエラーを解決する方法は、

「GROUP BYで指定したカラムをSELECTで選択する」

でした。

「基礎からのMySQL 第3版」のP.154の例で言うと、

SELECT bang FROM tb GROUP BY bang;

「基礎からのMySQL 第3版」のP.215の例で言うと、

SELECT 
  a.bang,a.nama,a.tosi,COUNT(*)
FROM tb1 AS a
  JOIN tb1 AS b
WHERE a.tosi<=b.tosi
  GROUP BY
a.bang,a.nama,a.tosi;

で「GROUP BY」句のエラーを出さずに処理結果を表示することができました。

今回は「基礎からのMySQL 第3版」という本の内容について沿って解説しました。

MySQLについて、他にも分からないことがありましたら、お問い合わせまでご連絡ください。

以上、ネットショップコンサルタントの「たぶ」でした。

こちらの記事もおすすめです。

MySQLとは

MySQLとは

2019年2月7日
「MAMP」の「MySQLモニタ」にパスを通す方法

「MAMP」の「MySQLモニタ」にパスを通す方法

2019年1月16日
MAMPを使ってWindowsにEC-CUBEのテスト環境を構築する方法

MAMPを使ってWindowsにEC-CUBEのテスト環境を構築する方法

2018年12月7日

【プログラミングならTechAcademy】


【いつでもどこでも受けられるTECH::CAMP】


ABOUTこの記事をかいた人

通称:たぶ
30代中頃、東京都在住。
ネットショップコンサルタント。
EC-CUBE、ASP、ショッピングモールなど各種ネットショップでの売上UPが得意。
アパレル系のネットショップの売上を4倍に増やし、月商900万円、年商1億円を達成。
ネットショップ運営の数なら誰にも負けません。
最近、ポメラニアンが気になる。
炊きたての白米が何もよりも好き。