用SQL找出前N名
业务系统中常常会有排名的需求,考试和比赛中则更普遍了。Excel 中也有个 Rank 函数供排名之用,数据库中更不例外了。
如果须要找出工资最高的前三个员工工资(及其员工号)。
只是。“前三名”的详细含义须要准确的定义。不然查出来的可能不是想要的结果。
首先。由于表中记录数可能就少于三,查出来的记录可能等于三条也可能少于三条。其次,须要考虑并列名次的处理。
- 假设名次不能并列,则还须要考虑是否要依据工资之外的列来区分排名。
比如:
名次 ID 工资
-------------
1 80 1000
2 90 1000
3 13 900 取前三名,则“4 19 900”不会被输出。 - 假设名次能够并列,则还有两种不同方式。
1)名次并列,可是兴许的名次要空出来。比如:
名次 ID 工资
-------------
1 80 1000
1 90 1000
3 13 9002)兴许的名次不空出来。
名次 ID 工资
-------------
1 80 1000
1 90 1000
2 13 900
在 Oracle 的演示样例数据库中。针对上述三种不同的情况能够通过不同的函数来实现。为了体现反复数据的影响,取了前5名。
- 用 ROW_NUMBER()。
SQL> select * from (select salary, row_number() over (order by salary desc) as seq from hr.employees) where seq <= 5; SALARY SEQ
---------- ----------
24000 1
17000 2
17000 3
14000 4
13500 5 - 用 RANK()。
SQL> select * from (select salary, rank() over (order by salary desc) as seq from hr.employees) where seq <= 5; SALARY SEQ
---------- ----------
24000 1
17000 2
17000 2
14000 4
13500 5 - 用 DENSE_RANK()。
SQL> select * from (select salary, dense_rank() over (order by salary desc) as seq from hr.employees) where seq <= 5; SALARY SEQ
---------- ----------
24000 1
17000 2
17000 2
14000 3
13500 4
13000 5
第一种须要的结果相对简单一点,可是结果集有些特殊(工资同样的人可能仅仅有一部分被选择出来)。在不支持 RANK() 的系统中。能够通过 LIMIT 等方式变通实现:
select employee_id, salary from hr.employee order by salary desc limit 5;
假设连 LIMIT 也没有,仅仅同意採用最主要的 SQL 构造。则更麻烦和低效。
基本思路是等价转换须要的查询“查工资的前五名”。比如:“工资的第1名”等价于“工资大于他的人为0人”。“工资的前5名”等价于“工资大于他的人不超过4人”。
也能够转换为“找出全部工资大于等于工资排名第五的人”。不要忘了处理排名并列的情况。
SQL> select employee_id, salary from hr.employees o where (select count(distinct employee_id) from hr.employees where salary > o.salary) < 5 order by 2 desc, 1 desc; EMPLOYEE_ID SALARY
----------- ----------
100 24000
102 17000
101 17000
145 14000
146 13500
用SQL找出前N名的更多相关文章
- 排序练习——找出前m大的数字 分类: 排序 2015-06-08 09:33 21人阅读 评论(0) 收藏
排序练习--找出前m大的数字 Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 给定n个数字,找出前m大的数字. 输入 多组输 ...
- 海量数据中找出前k大数(topk问题)
海量数据中找出前k大数(topk问题) 前两天面试3面学长问我的这个问题(想说TEG的3个面试学长都是好和蔼,希望能完成最后一面,各方面原因造成我无比想去鹅场的心已经按捺不住了),这个问题还是建立最小 ...
- [Oracle/SQL]找出id为0的科目考试成绩及格的学生名单的四种等效SQL语句
本文是受网文 <一次非常有意思的SQL优化经历:从30248.271s到0.001s>启发而产生的. 网文没讲创建表的数据过程,我帮他给出. 创建科目表及数据: CREATE TABLE ...
- Java/sql找出oracle数据库有空格的列
1.java方式 String table_sql = "select table_name from user_tables";//所有用户表 List<String> ...
- Oracle PL/SQL 找出100以内是3和5的倍数的数 循环语句
循环: loop --执行代码 exit when 表达式;--当表达式为真退出循环.(注意,其编写位置决定循环为先判断还是先执行,相当于java的while或do-while) end loop; ...
- SQL——找出某一字段中内容相同的数据
SELECT columnName from dbo.tableName group by columnName having count(*)>1
- sql 找出不包含字母、不包含汉字的数据
--1.不包含字母 SELECT * FROM t WHERE str NOT LIKE '%[a-zA-Z]%' SELECT * FROM t --2.不包含汉字 SELECT * FROM t ...
- 找出数组前N大的数
这个题也是个比较有名的面试题.当然有很多变种. 题目意思基本是:从一个数据量很大的数组里找前N大的元素.不允许排序. 这个题有两个比较好的思路: 思路一:用快速排序的思想,是思想,不是要排序; 思路二 ...
- 从一亿个ip找出出现次数最多的IP(分治法)
/* 1,hash散列 2,找到每个块出现次数最多的(默认出现均匀)—–>可以用字典树 3,在每个块出现最多的数据中挑选出最大的为结果 */ 问题一: 怎么在海量数据中找出重复次数最多的一个 算 ...
随机推荐
- JavaScript 实现表格单列按字母排序
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title> ...
- CentOS 7最小化安装图解
一.环境介绍: win10 x64安装VMware® Workstation 14 Pro(版本:14.1.2 build-8497320) 二.安装CentOS 1.新建虚拟机 打开虚拟机,主页,创 ...
- 【例题 8-4 UVA - 11134】Fabled Rooks
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 显然把问题分解成两个子问题. x轴和y轴分别做. 即n个点要求第i个点在[li,ri]范围内.(ri<=n) 问是否可行. 按 ...
- D3.js中对array的使用
由于D3类库和array密切相关,我们有必要讨论一下D3中的数据绑定以及在数组内部运算的方法. 1.D3中的数组 和其他编程语言一样,D3的数组元素可以是数字或者字符等类型,例如: someData= ...
- GO语言学习(十七)Go 语言类型转换
Go 语言类型转换 类型转换用于将一种数据类型的变量转换为另外一种类型的变量.Go 语言类型转换基本格式如下: type_name(expression) type_name 为类型,expressi ...
- 【CS Round #43 C】Rectangle Partition
[链接]点击打开链接 [题意] 有一辆火车,它的长度为L,然后假设这辆车现在随机可能地出现在0..D之间,然后假设它已经耗光了油. 问你它需要走的期望距离是多少. 这里要走的距离指的是车里最近的加油站 ...
- 洛谷—— P1069 细胞分裂
https://www.luogu.org/problem/show?pid=1069#sub 题目描述 Hanks 博士是 BT (Bio-Tech,生物技术) 领域的知名专家.现在,他正在为一个细 ...
- oled屏幕模块
oled屏幕模块似乎是厂家提供的 也许可以根据屏幕驱动芯片去写 根据现在了解的芯片一般有两个:SH1106和SSD1306 不过这次我们用的是SSD1306芯片驱动的屏幕 下面是从裸屏到模块的pcb: ...
- 快速创建SSH信任实现无密码登录
1. 生成本机的公私钥匙对[oracle@Oracle11_2 scripts]$ -t rsa Generating public/private rsa key pair. Enter file ...
- MySql开发之函数
1,在mySql常见的文本函数中常见的文本函数例如以下表所看到的: 2,数字函数例如以下: 3,日期和时间函数: 4,格式化日期和时间 使用的函数例如以下DATE_FORMAT()和TIME_FORM ...