问题
- 执行
SELECT * FROM person p GROUP BY p.age
时报错
错误代码: 1055
Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'xxl_job_test_2.p.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
CREATE TABLE `person` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(32) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO person (`id`, `name`, `age`) VALUES ('1', '张三', '20');
INSERT INTO person (`id`, `name`, `age`) VALUES ('2', '李四', '20');
INSERT INTO person (`id`, `name`, `age`) VALUES ('3', '王五', '21');
- 但是在有些项目中可以执行,原因是
MySQL 5.7
版本之后默认设置了sql_mode=only_full_group_by
,如果SELECT
的字段不在GROUP BY
中,
并且字段未使用聚合函数SUM、AVG、MAX、MIN
等,就会报错
解决方法
临时关闭ONLY_FULL_GROUP_BY
- 执行
SELECT @@GLOBAL.sql_mode;
,如果结果包含ONLY_FULL_GROUP_BY
则说明开启了ONLY_FULL_GROUP_BY
- 执行
SET GLOBAL sql_mode='STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
重新设置sql_mode
,这种方法只能临时解决,数据库重启失效
永久关闭ONLY_FULL_GROUP_BY
- 修改数据库配置文件
my.cnf
(windows系统是my.ini
),在[mysqld]
模块下新增一行sql_mode
配置,如下:
[mysqld]
default-time-zone = '+8:00'
default_password_lifetime=0
sql_mode='STRICT_TRANS_TABLESSTRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
- 配置后生效需要重启
MySQL
数据库
- 重启后执行
SELECT @@GLOBAL.sql_mode;
验证,结果不包含ONLY_FULL_GROUP_BY
说明配置生效
使用聚合函数
- 使用
ANY_VALUE
函数处理GROUP BY
之外的字段,修改后的SQL
如下:
SELECT ANY_VALUE(p.id),ANY_VALUE(p.name),p.age FROM person p GROUP BY p.age
ANY_VALUE
是获取分组的第一条数据,也可以使用SUM、AVG、MAX、MIN
等聚合函数