欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MySQL使用GROUP BY分组查询报错 ,ONLY_FULL_GROUP_BY解决方案

程序员文章站 2023-12-28 14:55:22
...

ysql5.7及以后默认sql_mode=“ONLY_FULL_GROUP_BY”。
含义:

sql中select后面的字段必须出现在group by后面,或者被聚合函数包裹,不然会抛出上面的错误 如以下错误:
Error Code: 1055. Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column ‘×××’ which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

废话就不多说了,目前整理的有以下方案:

方案1:SQL命令修改sql_mode(不建议使用)

--	1.使用select语句将sql_mode查询出来
select @@sql_mode;
-- 或者
select @@global.sql_mode;
-- 2.复制sql_mode结果,并将"ONLY_FULL_GROUP_BY"加进去,使用set或update语句更新sql_mode
set @@sql_mode =''; -- 改变已经存在的数据库sql_mode
set @@global.sql_mode=''; //改变全局配置sql_mode

这种方法是会话级别的,数据库重启后会失效。不建议在实际开发中使用。

方案2:配置文件修改sql_mode(不推荐使用)

不推荐使用的原因是,如果你不是DBA,也不是架构师,也不是领导我劝你别用,在大型项目中不可能因为你一个人菜而影响其他人的开发习惯或已有的开发规范。

Linux:

修改/etc/my.cnf文件使用编辑命令进行编辑,找到"[mysqld]“下的sql_mode,把"ONLY_FULL_GROUP_BY"j加进去并保存退出,然后使用命令"service mysqld restart"或”/etc/inint.d/mysqld restart"重启mysql服务。

windows:

修改MySQL文件下的/my.ini文件(默认安装请到C:\ProgramData\MySQL下找my.ini,自定义安装的自行查找或者百度),找到"[mysqld]"下的sql_mode,把"ONLY_FULL_GROUP_BY"j加进去,然后重启mysql服务器。不会用命令就按步骤来:我的电脑——(右键)管理——服务与应用程序——服务——MYSQL——开启(停止、重启动)。

方案3:GROUP_CONCAT()函数

使用GROUP_CONCAT()函数,语法:group_concat( [DISTINCT] 要连接的字段 [Order BY 排序字段 ASC/DESC] [Separator ‘分隔符’] ),我觉着意思就是在group by的前提下依据某个或多个字段进行排序,例如:insert_time,然后将每组排序后的某个字段进行拼接,例如:id,默认以英文","分割拼接。如果没看明白我讲的是啥,那您去百度一下吧。。。
例子:

SELECT ip, pc_name, GROUP_CONCAT( id ORDER BY collect_time DESC, insert_time DESC ) ids FROM t_sys_monitor GROUP BY ip, pc_name

结果:MySQL使用GROUP BY分组查询报错 ,ONLY_FULL_GROUP_BY解决方案
因为根据时间排序已经将需要最新一条数据id放在第一位了,所以使用SUBSTRING_INDEX(列名,截取分隔符,第几位)函数截取即可获取需要的id,然后多表关联查询得到结果。

SELECT
	t.id,
	t.ip,
	t.pc_name,
	t.status,
	t.collect_time,
	t.update_time,
	t.insert_time 
FROM
	t_sys_monitor t
	RIGHT JOIN ( SELECT SUBSTRING_INDEX( GROUP_CONCAT( id ORDER BY collect_time DESC, insert_time DESC ), ',', 1 ) id FROM t_sys_monitor GROUP BY ip, pc_name ) t1 ON t.id = t1.id 
ORDER BY
	t.collect_time DESC,
	t.insert_time DESC;

方案4:any_value()函数

待更新。。。

相关标签: SQL mysql

上一篇:

下一篇: