こんにちは。ネットショップコンサルタント「たぶ」(@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」句とは、「データベースに入っているデータを呼び出す時にグループとしてまとめる」ためのコマンドです。
たとえば、このように学校の生徒名簿があったとします。
カラム「class」で「GROUP BY」句を指定すれば、「1・2・3・4・5・・・」と各数字が入ったレコードをグループ化することができます。
同じ値が入ったレコードを「グループ」として扱うことで、各クラスの生徒数を数えたり、カラム「point」に入った点数の合計や平均などの集計をグループ単位で処理することができるようになるのです。
どのカラムを対象にグループ化するのかを指定するために「GROUP BY」句を使用します。
「GROUP BY」句の書き方は以下のとおり。
SELECT カラム名 FROM テーブル名 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
とエラーが出てしまいます。
エラーの内容を直訳してみると、
とのこと。
要するに、『「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」句がエラーになってしまう原因は、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で指定したカラムを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について、他にも分からないことがありましたら、お問い合わせまでご連絡ください。
以上、ネットショップコンサルタントの「たぶ」でした。
こちらの記事もおすすめです。