Tidb query sql report runtime error: index out of range [-1] error

cutting edge

When I was querying the Tidb database this afternoon, I suddenly found that an error was reported, but the same sql was executed on it without any problems. Finally, I found a problem with the sql mode. Tidb has a particularly strong constraint on the fields returned by group by.

text

solution

When we query Tidb, the following error message is reported

[42000][1055] Expression #18 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'ac_accounting.l.receipt_account_no' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by 

At first I wrapped the original sql in the outer layer, using select * from (original sql) group by uniq_data_id

After execution the error message becomes

 runtime error: index out of range [-1]

 The query information is due to the tidb version, but I haven't upgraded the version. Could it be an automatic upgrade? Damn it.

If we query the current sql_mode, execute the following sql 

show VARIABLES LIKE 'sql_mode';

You will find that it is only_full_group_by. If you carefully observe the first error message, you will find that the message has already prompted that sql_mode = only_full_group_by, but I didn’t notice this at the time.

The sql_mode mode is only_full_group_by, which roughly means that we are querying select * from a group by a.name similar to this sql statement, which does not satisfy the only_full_group_by mode. This mode requires the field of group by to be consistent with the field returned by the query. This may not be a tidb problem, but also the result of tidb's strong constraints in the only_full_group_by mode. We only need to close the only_full_group_by mode, and temporarily close it by executing the following sql

set sql_mode = '';

 After execution, we run the same sql just now, and there will be no problem

If you want to permanently close this mode, you need to modify the configuration file of mysql, find the configuration file /etc/my.cnf, and add it after [mysqld]

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

or

sql_mode = ''

Save it and save it in mysql.

extend

For reference, the definition of group by in SQL 92 is as follows

SQL-92 and earlier does not permit queries for which the select list, HAVING condition, or ORDER BY list refer to nonaggregated columns that are not named in the GROUP BY clause.

Translation: The non-aggregated fields after SELECT, HAVING, and ORDER must be exactly the same as the fields after GROUP BY

However, we often see that the fields queried by the sql statement in mysql are inconsistent with the fields of the group by. This is because new regulations have been made in SQL99, as shown below

SQL:1999 and later permits such nonaggregates per optional feature T301 if they are functionally dependent on GROUP BY columns: If such a relationship exists between name and custid, the query is legal. This would be the case, for example, were custid a primary key of customers.

Translation: If the fields after group by are primary keys, and the non-aggregate fields depend on the fields after group by, then you can put these non-aggregate fields after the SELECT, HAVING, ORDER BY statements.

But at this time the main character ONLY_FULL_GROUP_BY appeared, the meaning of this mode is similar to the restriction of SQL 92 on group by.
 

Guess you like

Origin blog.csdn.net/zanpengfei/article/details/125876124