ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

Mysql8的分组排序

2020-12-30 18:03:25  阅读:398  来源: 互联网

标签:audit GROUP Mysql8 cma 分组 message 排序 id


Mysql8之前Group By支持分组排序

如: 

select * 
from (
select * from user_position order by userId,time desc
) as u 
group by u.userId  

或如:

select * 
from  user_position 
group by userId  desc

  

会取每组时间最新的一条,官方给出解释:

默认情况下GROUP BY隐式排序(即,缺少GROUP BY列的ASC或DESC指示符)。但是,不推荐依赖于隐式GROUP BY排序(即,在没有ASC或DESC指示符的情况下排序)或GROUP BY的显式排序(即,通过对GROUP BY列使用显式ASC或DESC指示符)。要生成给定的排序 ORDER,请提供ORDER BY子句。 

但是在Mysql8之后不再支持这两种排序

具体原因:见 Removal of implicit and explicit sorting for GROUP BY

替代方式:

1、通过limit关键词,如:

select * 
from (
select * from user_position order by userId,time desc limit 9999
) as u 
group by u.userId  

使用limit之后,在group by 之前会保持排序

弊端:limit的数量有时候很难清楚

2、使用 in的方式

          SELECT
			*
		FROM
			message_audit cma LEFT JOIN message cm ON cm.id = cma.message_id
		WHERE
			cma.id IN ( SELECT max( id ) FROM message_audit GROUP BY message_id )

 弊端:in的id数量过大的话,效率极其低下,满足不了要求

3、使用窗口函数(分析函数) ROW_NUMBER() OVER()

在mysql8.0之后,开始支持窗口函数,我们可是使用窗口函数来完成分组排序,并且更加方便,如:

         WITH tb AS (SELECT
			cm.msg_title,
			cma.message_id,
			cma.id,
			cma.create_time,
			cma.audit_status,
			cma.audit_reason,
			cma.audit_time,
			cma.external_audit_status,
			cma.external_audit_reason,
			ROW_NUMBER () OVER ( PARTITION BY cma.message_id ORDER BY cma.create_time DESC ) AS RN 
		FROM
			message_audit cma LEFT JOIN message cm ON cm.id = cma.message_id
		WHERE
			cma.sys_audit_status = 1
	) SELECT * FROM tb  WHERE RN = 1

			 

  解释: ROW_NUMBER () OVER ( PARTITION BY cma.message_id ORDER BY cma.create_time DESC ) AS RN,根据 message_id来分组,根据 create_time来排序

获取的结果标记行号RN,最好根据RN=1来获取最新的记录,当然我们也可以获取最新的两条、三条记录,处理结果比第二种方法效果更好

标签:audit,GROUP,Mysql8,cma,分组,message,排序,id
来源: https://www.cnblogs.com/mlfz/p/14212740.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有