参考地址:https://www.cnblogs.com/qiuting/p/7880500.html

前排提示,下面的实例用到的hr.employees表是Oracle11g的orcl实例自带的表空间的表,不要说你没有~要是没有,你可能Oracle没装好,或者账号连查看这个表的权限都没有,你换个sysman等身份的账号进行登录,然后测试

普通SQL排序

Oracle本身对SQL有良好的支持,因此简单的排序,就可以使用order by子句

select * from hr.employess order by salary ;

排序后获得序号(row_num)

如果要求是排序,然后还要有一个专门的列给这些结果标序号,怎么办?

使用Oracle的rownum关键字和列名一起查询即可:

select rownum as rank, e.*  from hr.employees e order by salary desc ;

然而不能像上面直接这样查,会出现这种结果

因为rownum的机制的问题

正确的做法:嵌套一层子查询,先排序完,然后以这个排序好了的结果作为基表,再进行一次查询

select rownum as rank, e.* from
(select * from hr.employees order by salary desc) e;

这下就没问题了

使用排序函数

为什么使用排序函数?

有了上面的rownum关键字为什么还要有排序函数呢?请看上面的运行结果

应用场景考虑

排序的场景要考虑如下:

值不同的情况下:这个是最完美的情况了,现实肯定不可能。

有相同的值:按先来后到,这在一些比赛可能可以;或者并列第几,这个在成绩排名中是肯定的,不然分数一样,我凭什么我第二他第一,这个时候就只能使用Oracle的排序函数了

row_number()函数

row_number的用途非常广泛,排序最好用它,它会为查询出来的每一行记录生成一个序号,依次排序且不会重复,注意使用row_number函数时必须要用over子句选择对某一列进行排序才能生成序号。

row_number的简单使用

语法

select 别名.*, row_number() over(order by 子句 ) from 表名 别名;

实例

select e.*, row_number() over ( order by e.salary desc ) as rank from  hr.employees e ;

上面查看Oracle自带的雇员表中的员工按工资降序排序,但是以然不能解决我们需要并列排名的问题

row_number的分组排序

语法

select 别名.*, row_number() over(partition by 别名.排序字段 order by 子句 ) from 表名 别名;

实际操作

简单按工资降序别的也可以,那么你可以分组排序吗?例如我查看不同部们的人在他们自己的部门的工资排序,怎么写?

select e.*, row_number() over (partition by e.department_id order by e.salary desc ) as rank from  hr.employees e ;

加入了partiton by 通过哪个字段进行分组,然后排序,然而依然没有解决并列排名的问题!

rank()函数-主要解决over子句排序字段值相同的情况

rank函数用于返回结果集的分区内每行的排名,行的排名是相关行之前的排名数加一。简单来说rank函数就是对查询出来的记录进行排名,与row_number函数不同的是,rank函数考虑到了over子句中排序字段值相同的情况,如果使用rank函数来生成序号,over子句中排序字段值相同的序号是一样的,后面字段值不相同的序号将跳过相同的排名号排下一个,也就是相关行之前的排名数加一,可以理解为根据当前的记录数生成序号,后面的记录依此类推。

rank()的简单使用

语法

select 别名.*, rank() over(order by 子句 ) from 表名 别名;

实例

select e.*, rank() over ( order by e.salary desc ) as rank from  hr.employees e ;

上面的sql语句不但进行了排序,而且对字段值相同的情况做出了排序相同的处理,然而,却是1224的尴尬局面

rank的分组

rank的分组和row_number的分组一样,在over子句中加入partition by子句即可

语法

select 别名.*, rank() over(partition by 别名.分组字段 order by 子句 ) from 表名 别名;

实例

select e.*, rank() over (partition by e.department_id order by e.salary desc ) as rank from  hr.employees e ;

那么,有没有支持1223的排序函数呢?dense_rank函数!

dense_rank函数

dense_rank函数的功能与rank函数类似,dense_rank函数在生成序号时是连续的,而rank函数生成的序号有可能不连续。dense_rank函数出现相同排名时,将不跳过相同排名号,rank值紧接上一次的rank值。在各个分组内,rank()是跳跃排序,有两个第一名时接下来就是第三名,dense_rank()是连续排序,有两个第一名时仍然跟着第二名。

dense_rank的基本使用

语法

select 别名.*, dense_rank() over(order by 子句 ) from 表名 别名;

实际操作

select e.*, dense_rank() over ( order by e.salary desc ) as rank from  hr.employees e ;

dense_rank的分组排序

语法

select 别名.*, rank() over(partition by 别名.分组字段 order by 子句 ) from 表名 别名;

实际操作

select e.*, dense_rank() over (partition by e.department_id order by e.salary desc ) as rank from  hr.employees e ;

关于parttion by

  parttion by关键字是Oracle中分析性函数的一部分,用于给结果集进行分区。它和聚合函数Group by不同的地方在于它只是将原始数据进行名次排列,能够返回一个分组中的条记录(记录数不变),而Group by是对原始数据进行聚合统计,一般只有一条反映统计值的结果(每组返回一条)

使用排序函数的时候,空值是最大的,如果排序字段为null, 可能造成null字段排在最前面,影响排序结果。可以这样:

select 别名.*, row_number() over(partition by 别名.分组字段 order by 子句 nulls last) from 表名 别名;
select 别名.*, rank() over(partition by 别名.分组字段 order by 子句 nulls last ) from 表名 别名;
select 别名.*, dense_rank() over(partition by 别名.分组字段 order by 子句 nulls last ) from 表名 别名;

或者在排序前进行空值处理都可以

排序函数的使用注意

  1. 排名函数必须有 OVER 子句。
  2. 排名函数必须有包含 ORDER BY 的 OVER 子句。
  3. 分组内从1开始排序。

总结

不使用函数排序

使用SQL自己的group by和order by子句等进行"排序" "分组和排序":

比较麻烦,而且不能处理排序字段的值相同时的情况

使用Oracle的rownum关键字+sql的排序:

能够给查询的记录排序,并且给排序好的记录打上123这种序号,但也比较麻烦,需要在排序好的基础上再进行一次嵌套查询

使用函数排序

使用row_number函数:

可以排序,还可以分组排序,写起来比普通的sql的简洁的多,而且可以给排序的字段加序号,缺点是也无法处理排序字段的值相同时的情况

使用rank函数:

有row_number一样的效果,语法也相近,能处理排序字段的值相同时的情况,但是却是1224的模式(即相同的序号后面的序号会被跳过,也可以理解为占用)

使用dens_rank函数:

有row_number一样的效果,语法也相近,能处理排序字段的值相同时的情况,是1223的模式(即相同的序号后面的序号不会跳过)

三种函数的各自支持的模式的使用

1234还是1223还是1224要看具体的应用场景,没有说哪个就最好

要是1234是“先来后到”的规则的时候可以使用      假设是先到先得,那就算你成绩和我一样,你也不能有脾气

1224是“名额或者资源有限的”情况下用     假设奖励排名是第一到第五,就五张奖状,只能12245了

1223是“名额或资源充足”的时候用            假设奖励排名是第一到第五,奖状很多,就可以12222333344445555想怎么搞怎么搞

总结(码字)不易,帮助到了你,给个赞~~~~~

  

Oracle中的排序和排序函数的使用相关推荐

  1. oracle中类似indexof用法_instr函数

    oracle中类似indexof用法_instr函数 [sql] 在oracle中没有indexof()函数 但是提供了一个 instr() 方法 具体用法: select instr('保定市南市区 ...

  2. 【转】Oracle 中的 TO_DATE 和 TO_CHAR 函数 日期处理

    Oracle 中的 TO_DATE 和 TO_CHAR 函数 oracle 中 TO_DATE 函数的时间格式,以 2008-09-10 23:45:56 为例 格式 说明 显示值 备注 Year(年 ...

  3. Oracle 中的 TO_DATE 和 TO_CHAR 函数 日期处理

    Oracle 中的 TO_DATE 和 TO_CHAR 函数 日期处理 Oracle 中的 TO_DATE 和 TO_CHAR 函数 oracle 中 TO_DATE 函数的时间格式,以 2008-0 ...

  4. mysql中sql语句中常见的group_concat()函数意思以及用法,oracle中与其一样的功能函数是wmsys.wm_concat()

    1.group_concat(),手册上说明:该函数返回带有来自一个组的连接的非NULL值的字符串结果.比较抽象,难以理解. 通俗点理解,其实是这样的:group_concat()会计算哪些行属于同一 ...

  5. oracle中获取当前时间的函数

    在 Oracle 中,你可以使用 SYSDATE 函数来获取当前时间. 例如: SELECT SYSDATE FROM DUAL; 这会在输出中显示当前时间. 你也可以使用 CURRENT_TIMES ...

  6. Oracle中关于to_date(),to_char(),to_number()函数的用法

    一.Oracle中的to_date()函数 1.to_date()与24小时制表示法及mm分钟的显示: 在使用Oracle的to_date函数来做日期转换时,很多Java程序员也许会直接的采用&quo ...

  7. oracle中常使用到的函数,oracle中经常用到的函数

    最近学习oracle,在学习oracle函数时感觉网上千奇百怪的资源可读性太差,所以便拿来网络资源加以修改,并将其中的一起错误更正,因本人水平有限,有些地方可能还存在纰漏,还望各位前辈斧正. SQL中 ...

  8. oracle中的分隔函数,Oracle中的split字符串分割函数

    首先需要定义 2 个类型 1. Row 类型 CREATE OR REPLACE TYPE ty_row_str_split as object (strValue VARCHAR2 (4000)) ...

  9. oracle中按数字大小排序函数,oracle中分组排序函数用法

    项目开发中,我们有时会碰到需要分组排序来解决问题的情况,如: 1.要求取出按field1分组后,并在每组中按照field2排序:2.亦或更加要求取出1中已经分组排序好的前多少行的数据 这里通过一张表的 ...

  10. 小数点进位 oracle,使用多个小数点(。)对Oracle中的记录进行排序

    没有正则表达式和函数的解决方案(假设t是包含源数据的表): select * from t order by ( select sum( to_number(substr( sections, dec ...

最新文章

  1. 赢得高薪的锦囊三秘诀
  2. 京东某员工因加班太多引女友不满,下定决心离职:不想被迫加班!
  3. 双边滤波算法的原理、流程、实现及效果
  4. 35 个 Java 代码性能优化总结
  5. keep健身软件电脑版_一款不错的健身软件keep会员实现教程
  6. 机器学习:如何在安卓上集成TensorFlow
  7. c语言程序设计19,C语言程序设计19.pdf
  8. Shell 编程知识点集锦
  9. .NET中的数据结构——表
  10. 银联网关支付接口规范
  11. java jsp中文乱码怎么解决_如何解决JSP中文乱码问题
  12. 【C#】Winform常用属性和事件笔记大全(入门者参考)
  13. 李嘉诚14句经典成功格言
  14. 引用论坛、社区、问答系统的区别
  15. win10 开机无法自动连接或重启才能连接WIFI的简单解决方法/2022.03
  16. Unity3D FPS帧数修改
  17. 你该选择哪种编程语言来开发App呢?
  18. springboot+音乐播放小程序 毕业设计-附源码191730
  19. python 多列排序_python sorted多列排序
  20. 【面试题】面试题Redis

热门文章

  1. springboot集成支付宝支付2.0
  2. https://wenku.baidu.com/view/2a54b90e52ea551810a6874e.html
  3. 百度SEO推广怎么做?软文发稿推广的优势是什么?
  4. linux系统上的mysql开启远程链接
  5. [ Python ] 爬虫类库学习之 requests,爬取豆瓣喜剧电影排行榜
  6. 使用Virtualbox中的坑:双击鼠标或拖动鼠标就会自动切换视图模式
  7. 头文件里面声明的函数,到底加extern好还是不加extern呢?加不加都一样,默认是EXTERN。有时候没包含头文件编译也能找到函数,不报错只警告
  8. vue页面重置和刷新(vue数据重置)
  9. 【pyspark】jieba 中文分词
  10. 阿里月薪35k的B端产品经理,到底要懂多少业务?