SQL 第N个最高的薪水
找到表中第N个最高的薪水(第2nd、第3rd 或者第nth最高的薪水)是面试中最重要和最常见的问题。
在这里我们将展示给您一种最好且最简单的方式来编写 SQL 查询来找到表中第n个最高的薪水。
为了说明这一点,我们使用一个名为 “Emp” 的表,其中包含员工的详细信息,如员工ID(EID)、员工姓名(ENAME)和薪水(SALARY)。Emp表中的数据如下所示:
表名:Emp
EID | ENAME | SALARY |
---|---|---|
1 | Amit | 20000 |
2 | Bhaskar | 30000 |
3 | Chandan | 25000 |
4 | Durgesh | 28000 |
5 | Parul | 30000 |
6 | Garima | 25000 |
7 | Akshita | 28000 |
8 | Sonu | 40000 |
9 | Ravi | 37000 |
10 | Rajesh | 320000 |
查询数据库表Emp中计算第二高薪水的SQL查询
查询:1
SQL> select min(salary) from
(select distinct salary from emp order by salary desc)
where rownum < 3;
In order to calculate the second highest salary use rownum < 3
In order to calculate the third highest salary use rownum < 4
输出:
MIN(SALARY)
-----------
37000
Emp表中的结构和数据
输出屏幕
让我们来理解这个查询是如何工作的:
由于这个查询是嵌套的,让我们一步步理解每个部分:
第1步:首先,查询的这一部分将被执行,然后查询的外部部分将作用于此查询产生的结果:select distinct salary from emp order by salary desc
正如你所看到的,很少有员工得到相同的工资(例如Bhaskar, Parul和Chandan, Garima得到相同的工资,因此我们使用了不同的关键字,按工资排序desc将工资降序排列。
从emp订单中选择不同的工资输出按工资desc
SALARY
----------
40000
37000
32000
30000
28000
25000
20000
第2步:
SQL> select min(salary) from
(select distinct salary from emp order by salary desc)
where rownum < 3;
在第二步中,我们将嵌套查询的外部部分应用到从内部查询中获得的结果中。
Select min(salary) from:将选择min salary为20000,这不是第二高的薪水,因此我们使用了rownum < 3
, rownum < 3
只会给出从顶部开始的少于3的行数,即2。
rownum< 3
的输出将是:
SALARY
----------
40000
37000
第3步:现在选择min(salary)。
输出将是:
SALARY
----------
37000
37000是第二高的工资。
类似地找到:
要找到第三高的工资集’ rownum < 4 ‘
要找到第4高的工资集’ rownum < 5 ‘
等等……
计算数据库表名为 Emp 中第二高薪水的 SQL 查询
查询:2
select * from(
select ename, salary, dense_rank()
over(order by salary desc)rank from Emp)
where rank = & num;
为了计算第二高的工资,请使用num = 2
为了计算第三高的工资,请使用num = 3
等等……
输出:
ENAME SALARY Rank
------------ ---------- ----------
ravi 37000 2
让我们了解一下这个查询是如何工作的:
由于这个查询是嵌套的,让我们一步步理解每个部分:
第1步:首先,查询的这部分将被执行,然后查询的外部部分将作用于此查询产生的结果:
从Emp中选择ename, salary, dense_rank() over(order by salary desc)rank
Dense_rank()计算一组有序行中每一行的排名,并将排名作为数字返回。点数从整数1开始,以此类推。
如果我们讨论上述SQL查询,则根据emp表的salary返回rank。如果有两行或两行以上的值相等,那么所有的行都会被赋予相同的rank值。
如你所见,很少有员工获得相同的工资(例如Bhaskar, Parul和Chandan, Garima获得相同的工资,因此我们使用dense_rank(), desc将按工资降序安排工资。
select ename, salary, dense_rank() over(order by salary desc)rank from Emp
输出:
ENAME SALARY RANK
------------ ---------- ----------
sonoo 40000 1
ravi 37000 2
rohit 32000 3
bhaskar 30000 4
parul 30000 4
akshita 28000 5
durgesh 28000 5
garima 25000 6
chandan 25000 6
amit 20000 7
你可以从输出中看到,Bhaskar, Parul排名第四,因为他们都得到了相同的工资),Akshita, Durgesh排名第四(因为他们都得到了相同的工资),类似的Garima和Chandan。
第2步:
SQL> select * from(
select ename, salary, dense_rank()
over(order by salary desc)rank from Emp)
where r = &n
在第2步中,我们将嵌套查询的外部部分应用到从内部查询中获得的结果中。
Select * from
:将选择所有不是第二高工资的行,因此我们使用r = &n, r = &n将只根据用户为n输入的值给出匹配的行。如果n = 2的结果将是
n = 2时的输出为:
输入“n: 2”的值
old 1: select * from(select ename, salary, dense_rank() over(order by salary desc)r from Emp) where r=&n
new 1: select * from(select ename, salary, dense_rank() over(order by salary desc)r from Emp) where r=2
ENAME SALARY R
------------ ---------- ----------
ravi 37000 2
要找出第四高薪:
输入“n: 4”的“value”
old 1: select * from(select ename, salary, dense_rank() over(order by salary desc)r from Emp) where r=&n
new 1: select * from(select ename, salary, dense_rank() over(order by salary desc)r from Emp) where r=4
ENAME SALARY R
------------ ---------- ----------
bhaskar 30000 4
parul 30000 4
类似地,要找到:
找出第5高的工资集合n = 5
找出第6高工资的集合n = 6
等等……
计算数据库表名为Emp中第二高薪水的SQL查询
假设任务是计算上述表中第N高的员工薪水。操作步骤如下:
- 首先,要找出具有TOP n个不相似(distinct)薪水的员工。
- 计算上述查询结果中的所有薪水中的最低薪水,这样我们就得到了第N高的薪水。
- 从上述查询结果中,找出薪水最低的员工的详细信息。
查询编号:3
select * from emp where salary = ( select min( salary ) from emp
where salary IN (select distinct TOP N
salary from emp order by salary desc )
)
以上SQL查询将找出具有第n高工资的雇员的详细信息。
让我们详细看一下上述SQL查询的工作原理:
- 假设 n = 5。
服务器进行的处理是从最内部的查询开始,即查询:select distinct TOP 5 salary from emp order by salary desc
将生成以下结果:
• 40000
• 37000
• 32000
• 30000
• 28000
- 下一个外部查询是:
select min(salary) from emp where salary IN (之前SQL查询的结果)
。这将产生以下结果:
• 28000
有了以上的结果证明,所需的 第五 高的工资是28000。
- 最后,最外层的查询是:
select * from emp where salary = result of previous SQL query
。这个查询的结果将是拥有 第五 高工资的员工的详细信息。
• ________________________
• ename salary
• ________________________
• akshita | 28000
• |
查询的工作原理
由于这些查询是嵌套的查询,所以这个查询涉及到内部查询的使用。有两种版本的内部查询。 相关 和 不相关 查询。不相关的查询是指内部查询可以独立于外部查询运行的查询,而相关的查询是指内部查询与外部查询一起运行。我们计算第n个最高薪水的查询就是一个相关查询的例子。
SQL查询的性能分析
从上面的内容中,我们已经了解到内部查询在处理外部查询的每一行数据时都会执行一次,这最终会带来很多性能开销,特别是在行数非常大的情况下。
为了避免这种情况,建议使用特定于数据库的关键字来更快地获取结果。