最近遇到了一个需求,需要把数据先排序再分组,于是就想到了用order by 与grouy by 结合使用来处理,于是sql语句就出来了:
select * from aa order by 字段Bdesc group by 字段A
然后就报错了,好吧,原来group by 得放到 order by 前面使用,来换一下:
select * from aa group by 字段Aorder by 字段Bdesc
好的,sql正常执行了,好像没啥毛病,测试了一会儿,当数据量多的时候就发现,根据 B 排序没毛病,但是经过group by A 之后发现分组后查询出来的B的值是该组数据中的第一条,而不是最大的那一条。 很明显这样做就满足不了需求了,我要拿到的是最大的那一条,拿第一条没啥鸟用~ 如下:
排序分组后应该取出 aaa = 2 和 bbb = 3的数据 , 但是此sql语句 取出了 aaa = 1 与 bbb = 1 这些数据 , 查过资料后发现 group by 与 order by 同时使用的话 order by 并不能起到分组排序的效果。
于是就找到了 group_concat 与 substring_index 的组合分隔使用方法:
先用 group_concat 将分组后的 B 字段值从大到小组合起来 这样值就变成了
然后用 substring_index 方法取出数据中的第一个值然后根据第一个值来排序,咦,好像可以了,呈现出的数据为:
出现 3,2,1了 理想数据,很完美~~
最终呈现的sql为:
select SUBSTRING_INDEX(GROUP_CONCAT(B order by B DESC),',',1) as B, A, C from aa group by A order by B desc
发现数据正常了,可是后面发现数据达到两位数的时候,就出现问题了,如:
这就很奇怪,为啥根据最终呈现出的数据中最大的反而跑到中间去了,百思不得其解,后面和同事老王分析了一波后发现,原来SUBSTRING_INDEX切割后将int 的值类型转换成 string 类型了, 12被当做字符串来排序了 ,首位数字位1 所以 和 1 排在一起了 ,阿西吧,这个问题不好找,知道问题了就好办了,用mysql 的 转化函数 convert 将切割出来的首位值转换成 数值类型的就OK了。
于是sql为:
select convert(SUBSTRING_INDEX(GROUP_CONCAT(B order by B DESC),',',1),SIGNED) as B, A, C from aa group by A order by B desc
于是呈现出来的值为:
大功告成,仅以此篇记录order by 与 group by 结合使用的场景中碰到的问题以及解决思路。
领取专属 10元无门槛券
私享最新 技术干货