MySQL 1055 error - this is incompatible with sql_mode=only_full_group_by solution

foreword

Recently, the project encountered the need to query duplicate data in the database while excluding some historical data, so it is grouped by a certain field, and some fields of the data are taken out for display. This is the use of the group by statement. However, if mysql is In the higher version, when executing group by, if the selected field does not belong to the group by field, the SQL statement will report an error. The error message is as follows:

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

problem analysis

Principle level

This error occurs in mysql version 5.7 and above. The
default sql configuration of mysql version 5.7 and above is: sql_mode="ONLY_FULL_GROUP_BY", this configuration strictly implements the "SQL92 standard". When upgrading from 5.6 to 5.7, most of them will choose to adjust sql_mode to keep it consistent with 5.6 for syntax compatibility, in order to be as compatible as possible with the program.

sql level

When SQL is executed, the reason for this is simply:
because ONLY_FULL_GROUP_BY is enabled, if the selected field is not in the group by, and the selected field does not use an aggregate function (SUM, AVG, MAX, MIN, etc.), Then this sql query is considered illegal by mysql and will report an error

authentication problem

  1. Query the database version
SELECT VERSION();

insert image description here
It can be concluded that the database version on the server is 5.7.36
2. View the statement of sql_mode

select @@GLOBAL.sql_mode;

insert image description here
As can be seen in the value of query processing, sql_mode has enabled the only_full_group_by attribute

Solution

Method 1: Use the function ANY_VALUE() to include the error field

Use any_value() to include the field names in the sql statement that needs to be queried, and the result can be queried normally. Just change the alias of the query field as needed.

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

insert image description here
ANY_VALUE() function description:

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

Method 2: Temporarily modify sql_mode through sql statement

Remove ONLY_FULL_GROUP_BY and reset the value

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

The above is to change the global sql_mode, which is valid for the newly created database. For an existing database, you need to execute it under the corresponding database

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

Disadvantage: After restarting the mysql database service, ONLY_FULL_GROUP_BY will still appear, so this is only temporary.

Method 3: Permanently modify sql_mode through the configuration file

Mysql is installed on the server and installed locally, and the way to modify the configuration file is a little different.

1. Modify the configuration file under Linux

1) Log in to MySQL and
use the command mysql -u username -p to log in, then enter the password and enter SQL:

show variables like ‘%sql_mode’;

2) Edit the my.cnf file
The file address is generally in: /etc/my.cnf, /etc/mysql/my.cnf
Use the vim command to edit the file, find the location of sql-mode, remove ONLY_FULL_GROUP_BY
and restart MySQL;
some my. There may be no sql-mode in cnf, it needs to be added:

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) Restart the MySQL service after the modification is successful

service mysql restart

After restarting, log in to mysql and enter SQL: show variables like '%sql_mode'; If there is no ONLY_FULL_GROUP_BY, it means that it has succeeded. If
not, then only keep STRICT_TRANS_TABLES, NO_ENGINE_SUBSTITUTION
The additional content is:

sql-mode=STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION

reference article

MySQL error - this is incompatible with sql_mode=only_full_group_by perfect solution

Guess you like

Origin blog.csdn.net/ic_xcc/article/details/125186285