春からWHIにてITエンジニアをしているhinoです
今回はMySQL触っている際に遭遇した以下のエラーについて解決に至るまでをまとめてみました。
which is not functionally dependent on columns in GROUP BY clause;
this is incompatible with sql_mode=only_full_group_by
どういう状況で起きたのか
SQLでGROUP BY句を使って集計をして、SELECTでカラムを表示する際にこのエラーが出ました。
例として商品の販売金額や販売個数を記録するテーブル(items)があると仮定します。
- item_code: 商品コード
- item_amount: 販売個数
- sale_amount: 販売金額
- sale_date: 販売日
このテーブルに対して販売金額を集計したいとして以下のクエリを実行すると最初に記載されたエラーが出ます。
SELECT item_code, SUM(sale_amount), sale_date
FROM items
GROUP BY item_code;
エラー
Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column
'hoge.items.sale_date' which is not functionally dependent on columns in GROUP BY clause;
this is incompatible with sql_mode=only_full_group_by
このエラーの意味は以下の通りです。
「SELECTの3番目の式(items.sale_date)がGROUP BYされていない(=集約されていない)ので、不正なクエリとなっている」
解決策
MySQLのリファレンス を見てみると、only_full_group_by
モードである場合は GROUP BYで指定していなく、関数従属をしていないカラムを参照するクエリはエラーを出力するようにしているようです。
以上のことから、集計されていないカラムについては出力をしないという方法が有効になります。
つまりは集計関数やGROUP BYを使っていないカラムは集計をした際にはSELECTしないようにすることで解決できます。
先ほどのクエリだと sale_date が集計されていないカラムになりますので、sale_date を除外することでクエリが正常に処理されます。
SELECT item_code, SUM(sale_amount)
FROM items
GROUP BY item_code;
他にもonly_full_group_by
モードを無効にする、ANY_VALUE()
を使うといった方法がありますが割愛します...。詳細はMySQLのリファレンス をご確認ください。
まとめ
- タイトルのエラーは集計時に関数従属をしておらず、集計されていないカラムをSELECTすることで発生
- 修正策の一つに非集計カラムをSELECTしないようにする方法がある