1. ホーム
  2. mysql

[解決済み] MySql でクエリ実行時に only_full_group_by に関連するエラーが発生する。

2022-03-19 22:48:52

質問

システムをアップグレードし、作業中のウェブアプリケーション用にMySql 5.7.9とphpをインストールしました。動的に作成されるクエリがあり、MySql の古いバージョンで実行すると問題なく動作します。 5.7 にアップグレードしてから、このエラーが発生するようになりました。

SELECTリストの式番号1がGROUP BY句に含まれておらず、かつ 非集計カラム 'support_desk.mod_users_groups.group_id' は、以下の通りです。 GROUP BY 節のカラムに機能的に依存しない。 sql_mode=only_full_group_byと互換性がありません。

Mysql 5.7 のマニュアルページにある サーバーSQLモード .

このクエリで問題が発生しています。

SELECT mod_users_groups.group_id AS 'value', 
       group_name AS 'text' 
FROM mod_users_groups
LEFT JOIN mod_users_data ON mod_users_groups.group_id = mod_users_data.group_id 
WHERE  mod_users_groups.active = 1 
  AND mod_users_groups.department_id = 1 
  AND mod_users_groups.manage_work_orders = 1 
  AND group_name != 'root' 
  AND group_name != 'superuser' 
GROUP BY group_name 
HAVING COUNT(`user_id`) > 0 
ORDER BY group_name

この問題についてググってみましたが、よくわかりません。 only_full_group_by クエリを修正するために必要なことを理解するのに十分です。単に only_full_group_by それとも他に何か必要なものがあるのでしょうか?

もっと情報が必要なら教えてください。

解決するには?

私なら group_idGROUP BY .

いつ SELECT の一部でないカラムを使用すること。 GROUP BY の場合、グループ内にはそのカラムの値が複数存在する可能性がありますが、結果には1つの値しか表示されないことになります。そのため、データベースの 通常 は、これらの複数の値を1つの値にする方法を正確に伝える必要があります。一般的に、これは以下のような集約関数で行われます。 COUNT() , SUM() , MAX() などなど... と言うと 通常 というのも、他の一般的なデータベースシステムは、これを強く要求しているからです。しかし、バージョン 5.7 以前の MySQL では、デフォルトの動作はより寛容で、文句を言わず、任意に 任意の値 ! また ANY_VALUE() この関数は、もし本当に以前と同じ動作が必要なら、この質問に対する別の解決策として使うことができます。この柔軟性は、非決定的であるという代償を伴うので、よほど必要な理由がない限りはお勧めしません。MySQL は現在 only_full_group_by の設定に慣れて、クエリをそれに準拠させるのがベストです。

では、なぜ上記のようなシンプルな答えになったのか?いくつかの前提があるからです。

1) group_id は一意である。合理的と思われる、結局のところ「ID」である。

2) group_name も一意である。これは、それほど合理的な仮定ではないかもしれません。もしそうでなく、重複する group_names を追加し、私のアドバイスに従って group_idGROUP BY というのも、同じ名前のグループが別々の行として結果に表示されるようになったからです。私にとっては、データベースが静かに任意の値を選択したために、重複するグループが隠されてしまうよりも、こちらの方が良いと思います。

また、複数のテーブルがある場合は、すべてのカラムにテーブル名またはエイリアスを付けて修飾するのもよい方法です。

SELECT 
  g.group_id AS 'value', 
  g.group_name AS 'text' 
FROM mod_users_groups g
LEFT JOIN mod_users_data d ON g.group_id = d.group_id 
WHERE g.active = 1 
  AND g.department_id = 1 
  AND g.manage_work_orders = 1 
  AND g.group_name != 'root' 
  AND g.group_name != 'superuser' 
GROUP BY 
  g.group_name, 
  g.group_id 
HAVING COUNT(d.user_id) > 0 
ORDER BY g.group_name