(作者:陈玓玏)
排序是非常常见的数据处理需求,Oracle中也有很多排序的方法,下面一起看看吧。
1、row_number实现分组排序后按序号取值
select * from
(
SELECT
ROW_NUMBER() over(partition by user_id order by calltime desc) as rowNum
,user_id
,calltime
FROM tablename
) t
where t.rowNum = 1
上面这段代码的功能就是:根据用户id分组,在组内根据calltme进行从近到远的时间降序排列,并在表中新增一列rowNum,用于存放记录在组内的时间排序情况,并在外层查询中选取组内的第一条记录,从而实现选择每个用户最近的一次calltime的功能。
这个功能好用是好用,但是只有Oracle有这个函数,MySQL中是没有row_number这个函数的,需要自己另外去实现。
2、rank跳跃排序
select * from
(
SELECT
RANK() over(partition by user_id order by calltime desc) as rowNum
,user_id
,calltime
FROM tablename
) t
where t.rowNum = 1
rank函数和row_number功能类似,但是是跳跃排序,也就是说,当有两个并列第三时,就不会有排名为四的记录,而是直接跳到排名五了。
3、dense_rank连续排序
select * from
(
SELECT
DENSE_RANK() over(partition by user_id order by calltime desc) as rowNum
,user_id
,calltime
FROM tablename
) t
where t.rowNum = 1
功能和rank一样,但是排名不会跳过,如果有两个并列第一,两个并列第二,那么前四名的排序就会是1,1,2,2,不像rank,在这种情况下rank的排序结果会是1,1,3,3。
4、oder by
select * from mysql_study.score order by degree
select * from mysql_study.score group by user_id order by degree
上面两句用法有些不同,第一句会直接对所有记录进行排序,而第二句看上去是对所有的分组进行组内排序,但其实际实现的功能是选取每个用户的degree中选择分数较低的那个,然后再排序。也就是会去掉很多id重复的记录,所以如果想实现组内排序,用这种方法还是不靠谱,用上面的更好。