前言:
有很多东西经常在用,但是却有很多细节没有注意到,有一天突然发现原有还有这种限制呢,发现原来小丑是自己。
今天这篇文章就讲解下mysql使用group by和distinct关键字容易出现的问题!
正文:
废话不多说,还是先复现问题!
一、复现问题
1.我们先新建一张表,如下图所示
2.我们按名字分组统计下数量,查出改名字的id
SELECT
id,name,sum(num)
FROM
test1
GROUP BY
NAME
3.运行sql,发现报错
055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'bendi.test1.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
意思就是查询的字段,并没有在分组字段里,不符合sql_mode的only_full_group_by模式
敲重点
这时候网上搜到很多文章,会说让你去修改数据的sql_mode,然后你试了下,发现还真的不错了,那你可真是入坑了。千万不要去修改sql_mode,因为你想想软件为什么要默认不支持这样的sql写法,肯定有它的道理。
我们仔细分析下上面sql的写法和数据,第6条数据和第7条数据的名字一致,如果我们修改了数据库的模式在执行下sql会发生什么呢?
我们发现最后id取的是6,mysql最后给我们取了第一条。 这样你查询出来的这个id,实际业务也是不准确的。所以为了避免这种取第一条的情况,mysql在5.7版本后默认的sql_mode模式是only_full_group_by模式。这也是为什么group by分组查询的时候,select字段一定要出现在group by后。
再次强调一定不要去改sql_mode,因为那样分组查出来的数据是不准确的。
二、解决问题
select中的字段如何不在聚合函数中必须出现在group by中 ,这样在不改sql mode的情况,也不会报错。
但是这样分组的意义就不在了,不过你仔细想下,其实按名字分组统计数量,本身查出分组的id也是没有业务含义的,所以这样不需要查询id。所以在大多数情况下,如果你报了开头的错误,基本你查询的这个字段都不太需要。
总结:
在网上写的博客解决了问题,不一定就是正确的,因为就会像本文提到的这种情况,有可能是假解决,所以大家一定要自己去检验下。当然如果大家对group by字段理解到位的话,一开始就不会这样使用。希望小伙们看到网上在出现查询字段不在聚合函数中,也不在group by后面,一定要评论提醒。
我是阿达,一名喜欢分享知识的程序员,时不时的也会荒腔走板的聊一聊电影、电视剧、音乐、漫画,这里已经有15981位小伙伴在等你们啦,感兴趣的就赶紧来点击关注我把,哪里有不明白或有不同观点的地方欢迎留言!