是否有任何预定义的函数或方法可用于从员工表中获得第二高的薪水?
5 回答
执行此操作的方法是使用 Oracle 的分析功能。您的特定场景只是我在另一个线程中提供的解决方案的一个变体。
如果您只想选择第二高的薪水,那么 DENSE_RANK()、RANK() 和 ROW_NUMBER() 中的任何一个都可以解决问题:
SQL> select * from
2 ( select sal
3 , rank() over (order by sal desc) as rnk
4 from
5 ( select distinct sal
6 from emp )
7 )
8 where rnk = 2
9 /
SAL RNK
---------- ----------
3000 2
SQL>
但是,如果您要选择其他信息,例如薪水第二高的员工的姓名,您选择的功能会影响结果。选择一个而不是另一个的主要原因是出现平局时会发生什么。
如果你使用 ROW_NUMBER() 它将返回按薪水排序的第二个员工:如果有两个员工并列最高薪水怎么办?如果有两名员工并列第二高的薪水怎么办?如果您使用 RANK() 并且有两名员工并列第一高薪,则不会有RANK = 2 的记录。
我建议 DENSE_RANK() 在这些情况下通常是最安全的选择,但它确实取决于特定的业务需求。
在 Oracle 中,您将使用这样的查询来返回分页结果(行 M 到 N):
SELECT NAME, salary
FROM (SELECT NAME, salary, ROWNUM r
FROM (SELECT NAME, salary
FROM employee
ORDER BY salary DESC
)
WHERE ROWNUM <= :N
)
WHERE r >= :M
或者,您可以使用分析:
SELECT NAME, salary
FROM (SELECT NAME, salary, row_number() over (ORDER BY salary DESC) n
FROM employee)
WHERE n BETWEEN :M AND :N
如果你想从表中找到 n 个最高的薪水,你可以使用这个:
select min(sal)from (select distinct sal from emp order by sal desc) where rownum<=n;
其中 n 是 1,2,3, ..., n
从表中找出最高工资是一个非常简单的过程。
尝试这个:
SELECT * FROM employee emp WHERE 2=(SELECT COUNT(*) FROM employee WHERE
salary >= emp.salary);
处理 引入这种语法的Top-N
查询更容易:Oracle DB 12c
[ OFFSET offset { ROW | ROWS } ]
[ FETCH { FIRST | NEXT } [ { rowcount | percent PERCENT } ]
{ ROW | ROWS } { ONLY | WITH TIES } ]
用于ORDER BY
列表后的查询。
在这种情况下,请考虑使用:
select *
from emp
order by sal desc
offset 1 rows fetch next 1 rows only
其中 usingoffset
是可选的,从语法中已经可以看出,并指出fetch
子句的起点将是offset + 1
.
一种特殊情况是,ties
这意味着多行匹配第 N 行的值(这里我们需要第 2 行)。如果排名第二的职位有多于一个人的薪水相同,那么我们需要将only
关键字替换with ties
为全部返回:
select *
from emp
order by sal desc
offset 1 rows fetch next 1 rows with ties