MySQL 1055 エラー - これは sql_mode=only_full_group_by ソリューションと互換性がありません

序文

最近、プロジェクトでは、一部の履歴データを除外しながらデータベース内の重複データをクエリする必要があるため、特定のフィールドでグループ化し、データの一部のフィールドを取り出して表示します。これは、group by ステートメントの使用です。ただし、mysql が上位バージョンの場合、group by を実行する際、選択したフィールドが group by フィールドに属さない場合、SQL ステートメントはエラーを報告します。エラーメッセージは次のとおりです。

1055 - Expression #1 of SELECT list is not in GROUP BY 
clause and contains nonaggregated column
 'data_export.TrustDataController_store_chain_data_info_method.block_height' 
 which is not functionally dependent on columns in GROUP BY clause; 
 this is incompatible with sql_mode=only_full_group_by, Time: 0.004000s

問題分析

原則レベル

このエラーは、mysql バージョン 5.7 以降で発生します。mysql
バージョン 5.7 以降のデフォルトの SQL 構成は、sql_mode="ONLY_FULL_GROUP_BY" であり、この構成は厳密に「SQL92 標準」を実装しています。5.6 から 5.7 にアップグレードする場合、ほとんどの場合、プログラムとの互換性を可能な限り保つために、構文の互換性のために sql_mode を 5.6 との一貫性を保つように調整することを選択します。

SQLレベル

SQL の実行時にこの理由は単純です。
選択したフィールドがグループ化に含まれておらず、選択したフィールドが集計関数 (SUM、AVG、MAX、MIN など) を使用していない場合に ONLY_FULL_GROUP_BY が有効になっているためです。 , その後、この SQL クエリは mysql によって不正とみなされ、エラーが報告されます。

認証の問題

  1. データベースのバージョンを問い合わせる
SELECT VERSION();

ここに画像の説明を挿入
サーバー上のデータベースのバージョンは 5.7.36 であると結論付けることができます。
2. sql_mode のステートメントを表示します。

select @@GLOBAL.sql_mode;

ここに画像の説明を挿入
クエリ処理の値からわかるように、sql_mode はonly_full_group_by 属性を有効にしています。

解決

方法 1: 関数 ANY_VALUE() を使用してエラー フィールドを含める

any_value() を使用して、クエリする必要がある SQL ステートメントにフィールド名を含めると、結果は通常どおりクエリできます。必要に応じてクエリ フィールドのエイリアスを変更するだけです。

SELECT  ANY_VALUE(`block_height`) as block_height, ANY_VALUE(`block_time_stamp`) as block_time_stamp, ANY_VALUE(`tx_hash`) as tx_hash, `_key_ID`, 
ANY_VALUE(`_chain_data_ID`) as _chain_data_ID, ANY_VALUE(`_chain_data_index`) as _chain_data_index, ANY_VALUE(`output1`) as output1
FROM `TrustDataController_store_chain_data_info_method` 
WHERE (_chain_data_index LIKE "%各地级市数据6d767fc5d458fdb0139d6ad0fe69ec91%") GROUP BY _key_ID ORDER BY ANY_VALUE(`block_time_stamp`) desc

ここに画像の説明を挿入
ANY_VALUE() 関数の説明:

MySQL有any_value(field)函数,它主要的作用就是抑制ONLY_FULL_GROUP_BY值被拒绝。
这样sql语句不管是在ONLY_FULL_GROUP_BY模式关闭状态还是在开启模式都可以正常执行,不被mysql拒绝。
any_value()会选择被分到同一组的数据里第一条数据的指定列值作为返回数据。
官方有介绍:https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_any-value

方法 2: SQL ステートメントを使用して sql_mode を一時的に変更する

ONLY_FULL_GROUP_BY を削除し、値をリセットします

SET @@global.sql_mode ='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';

上記は、新しく作成されたデータベースに有効なグローバル sql_mode を変更することです。既存のデータベースの場合は、対応するデータベースで実行する必要があります。

SET sql_mode ='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';

欠点: mysql データベース サービスを再起動した後も、ONLY_FULL_GROUP_BY が表示されるため、これは一時的なものにすぎません。

方法 3: 構成ファイルを使用して sql_mode を永続的に変更する

Mysqlはサーバー上にインストールされるものとローカルにインストールされるもので、設定ファイルの変更方法が少し異なります。

1. Linux で設定ファイルを変更します。

1) MySQL にログインし、
コマンド mysql -u username -p を使用してログインし、パスワードを入力して SQL を入力します。

show variables like ‘%sql_mode’;

2) my.cnf ファイルを編集します。
ファイル アドレスは通常、/etc/my.cnf、/etc/mysql/my.cnf にあります。vim
コマンドを使用してファイルを編集し、SQL モードの場所を見つけて、ONLY_FULL_GROUP_BY を削除し
、 MySQL を再起動します
。cnf に SQL モードがない可能性があるため、追加する必要があります。

sql-mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

3) 変更が成功したら、MySQL サービスを再起動します。

service mysql restart

再起動後、mysql にログインして SQL を入力します: show variables like '%sql_mode'; ONLY_FULL_GROUP_BY がない場合は、成功したことを意味します。そうでない場合は、STRICT_TRANS_TABLES、NO_ENGINE_SUBSTITUTION のみを保持します。追加の内容は次のとおり
です

sql-mode=STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION

参考記事

MySQL エラー - これは sql_mode=only_full_group_by の完璧なソリューションと互換性がありません

おすすめ

転載: blog.csdn.net/ic_xcc/article/details/125186285