背景:
例如,给你一张用户表,还有一张地区信息表(每条数据都是到省 - 市 - 县 的地区信息,具体到县区),用户表中有用户所在市区字段,你要根据 地区信息表 查用户的所在市区的市区编码。就会出现一个情况,用户表 左连接 地区信息表 根据市区信息去匹配,一对多(比如惠州有7的县区),这个时候你只要随机的一条就够不需要多条,现在就考虑如何去重
sql大概如下:
select 用户表id, 用户字段,市区编码
from 用户表
left join 地区信息表 on 用户市区 = 地区表市区
尝试一:
使用 DISTINCT
修改sql:
select DISTINCT 用户表id, 用户字段,市区编码
from 用户表
left join 地区信息表 on 用户市区 = 地区表市区
结果:
没用,原因是 mysql的DISTINCT关键字,是后面跟多少个字段,就是多少个字段一起组合,组合后所有字段一样才会去重, 并不是说你在id前面,就会对id字段一样的数据去重(老实说个人觉得这个关键字很鸡肋,查询的所有字段完全一样才去重,基本就是相当于表中有两条一模一样的数据,一般都不可能),由于市区编码不同县区不一样,所以这个关键字根本去不了重
尝试二:
使用分组 group by
修改sql:
select 用户表id, 用户字段,市区编码
from 用户表
left join 地区信息表 on 用户市区 = 地区表市区
group by 用户表id
结果:
可以实现,因为根据分组后,多条数据的用户id是相同的,分到同一组,所以查询就剩下一条了,这样你取到的市区编码就是随机的一条
但是,银行mysql后面的版本有个ONLY_FULL_GROUP_BY 这个设置,大概的意思就是,你如果使用group by,那么你的select 的字段必须是group by中的分组字段,或者其他的使用了聚合函数的字段。所以 (select 用户表id, 用户字段,市区编码 ) 是会报错的,只能用 (select 用户表id),或者根据三个字段一起分组(group by 用户表id, 用户字段,市区编码 ),但是又相当于没分组了,而且正常的项目查询的字段何止三个,肯定不能都分组,效率很低,所以也不行,除非你关了上面这个ONLY_FULL_GROUP_BY ,或者使用低版本mysql
尝试三:
这次是使用子查询的方法,在子查询中使用group by,让子查询里变成一个市区一条数据而不是原来的一个县区一个数据
修改sql:
select 用户表id, 用户字段,市区编码
from 用户表
left join
(select 地区表市区 ,max(市区编码)
from 地区信息表
group by 地区表市区
) as d
on 用户市区 = d.地区表市区
结果:
成功,在子查询中,用分组已经得到一个市区一条数据,然后用max聚合函数查到最大的市区编码(相当于随机获取其中一条),这样子查询和用户表的数据就是一对一,就可以实现我们的需要
结语:
上送需求是我根据我实际工作遇到的举例出来的,相信也有不少朋友遇到相同的,上述仅代表我个人的处理过程和意见,如果朋友们有其他更好的方法也请不吝赐教,谢谢