Mysql实现先排序后分组排序的需求

在工作中做报表的时候,需要按创建时间排序,然后再对某些字段进行分组排序。
首先遇到的问题是以前使用oracle数据库时可以使用分组排序函数直接排序,由于切换到了Mysql数据库,所以不能使用相同的解决方法。查找相关资料后得出了一些灵感。oracle分组排序函数如下(复习下):

Oracle中row_number()、rank()、dense_rank() 的区别:
		--row_number() 顺序排序 1 2 3 4 5 
		--rank() 跳跃排序,如果有两个第一级别时,接下来是第三级别 1 2 2 4 5
		--dense_rank() 连续排序,如果有两个第一级别时,接下来是第二级别  1 2 2 3 4
			关于Parttion by:
				Parttion by关键字是Oracle中分析性函数的一部分,用于给结果集进行分区。它和聚合函数Group by不同的地方在于它只是将原始数据进行名次排列,能够返回一个分组中的多条记录(记录数不变),而Group by是对原始数据进行聚合统计,一般只有一条反映统计值的结果(每组返回一条)。
			总结:
				在使用排名函数的时候需要注意以下三点:
				1、排名函数必须有 OVER 子句。
				2、排名函数必须有包含 ORDER BY 的 OVER 子句。
				3、分组内从1开始排序。
			TIPS:
				使用rank over()的时候,空值是最大的,如果排序字段为null, 可能造成null字段排在最前面,影响排序结果。
				(使用rank()/dense_rank() 时,必须要带order by否则非法)
			可以这样: rank over(partition by course order by score desc nulls last) 

Mysql的分组排序功能实现如下(我是按照两个字段进行分组的排序的):

select t.*,IF(@tmp=t.appr_node_name and @tmp1=t.stage,@rank:=@rank + 1,@rank:=1) as rownum,
		 @tmp:=t.appr_node_name as tmp,
			@tmp1 :=t.stage as tmp1
 from (select rmt_work_appr_record.appr_record_id,rmt_work_appr_record.appr_node_id,
		 rmt_work_appr_record.approver_name,
	   rmt_work_appr_record.appr_node_name,
	   rmt_work_appr_record.stage,
	   rmt_work_appr_record.created_dt
from rmt_work_appr_record
where work_permit_id = 2000000004181 
GROUP BY appr_node_id,approver_name,appr_node_name,stage ORDER BY created_dt) t; -- 按顺序遍历累计,顺序非常重要,直接会影响查询排序的正确性

效果如下:
查询结果
可是这里的创建时间字段created_dt 并没有按照原有的语义进行排序。查阅资料后知道Mysql按照先分组后排序的顺序执行,所以最后的order by子句没有生效。可以使用子查询解决。
未分组的查询结果如下:
在这里插入图片描述
可以看出分组排序并未按照创建时间的逆序查询出相应的效果。于是尝试先使用子查询进行排序,然后再进行分组排序。

select t2.*,IF(@tmp=t2.appr_node_name and @tmp1=t2.stage,@rank:=@rank + 1,@rank:=1) as rownum,
		 @tmp:=t2.appr_node_name as tmp,
			@tmp1 :=t2.stage as tmp1
 from (
select t.appr_record_id,t.appr_node_id,
		 t.approver_name,
	   t.appr_node_name,
	   t.stage,
	   t.created_dt
from
(select  rmt_work_appr_record.appr_record_id,rmt_work_appr_record.appr_node_id,
		 rmt_work_appr_record.approver_name,
	   rmt_work_appr_record.appr_node_name,
	   rmt_work_appr_record.stage,
	   rmt_work_appr_record.created_dt
from rmt_work_appr_record
where work_permit_id = 2000000004181 ORDER BY created_dt desc) t GROUP BY t.appr_node_id,t.approver_name,t.appr_node_name,t.stage) t2;

先通过子查询进行排序,然后再进行分组,最后使用临时变量记录分组排序的值:
在这里插入图片描述
现在就实现了先排序后分组排序的需求了。
参考资料:
分组排序
Mysql下实现先排序后分组

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值