Oracle分组排序查询

2,394 阅读1分钟

第一种group by 语法

经常使用group by将这些数据按照性别进行分组:
SELECT * FROM STUDENT GROUP BY SEX; 不幸的是,执行失败了,提示:不是 GROUP BY 表达式!
原因是group by 分组查询,select子句后的字段必须来自group by后的分组字段。
修改后的sql:
SELECT SSEX FROM STUDENT GROUP BY SEX;

前面说的可能无法满足你想要的结果

第二种row_number() over()

介绍

row_number() over(partition by col1 order by col2) 根据col1分组,在分组内部根据col2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的)。

sql

select rk.*,
       row_number() over(partition by riskcode order by versioncode desc) row_number
  from aa_riskpolicy rk

查询的结果:

image.png

第三种rank() over()

介绍

rank()是跳跃排序,有两个第二名时接下来就是第四名。

sql

select t.*,rank() over(partition by accno order by createDate) rank from Test t 

查询的结果:

image.png
根据时间排序的,时间重复的时候,rank也是重复的。

第四种dense_rank() over()

介绍

dense_rank()也是连续排序,有两个第二名时仍然跟着第三名。

sql

select t.*,dense_rank() over(partition by accno order by createDate) dense_rank from Test t

查询的结果:

image.png
可以发现相同CREATEDATE的两个字段是两个第2时接下来就是第3。

分组排序后分别取出各组内前多少的数据记录

思路:需要用到子查询,先将数据进行分组排序,然后再分组排序后的数据中筛选符合条件的数据

sql 查询每组前3条

select createDate, accno, money, row_number
  from (select t.*,
               row_number() over(partition by accno order by createDate) row_number
          from Test t) t1
 where row_number < 4

查询的结果:

image.png