您如何编写查询,其中仅返回选定数量的行以及最高或最低列值。
即 5 名最高薪员工的报告?
最好的方法是使用分析函数 RANK() 或 DENSE_RANK() ...
SQL> select * from (
2 select empno
3 , sal
4 , rank() over (order by sal desc) as rnk
5 from emp)
6 where rnk <= 5
7 /
EMPNO SAL RNK
---------- ---------- ----------
7839 5000 1
7788 3000 2
7902 3000 2
7566 2975 4
8083 2850 5
7698 2850 5
6 rows selected.
SQL>
DENSE_RANK() 在出现平局时压缩间隙:
SQL> select * from (
2 select empno
3 , sal
4 , dense_rank() over (order by sal desc) as rnk
5 from emp)
6 where rnk <= 5
7 /
EMPNO SAL RNK
---------- ---------- ----------
7839 5000 1
7788 3000 2
7902 3000 2
7566 2975 3
8083 2850 4
7698 2850 4
8070 2500 5
7 rows selected.
SQL>
您喜欢哪种行为取决于您的业务需求。
还有 ROW_NUMBER() 分析函数,我们可以使用它来返回精确的行数。但是,我们应该避免使用基于行号的解决方案,除非业务逻辑乐于在出现平局时任意截断结果集。要求五个最高值和按高值排序的前五个记录之间存在差异
还有一个使用 ROWNUM 伪列的非解析解。这很笨拙,因为在 ORDER BY 子句之前应用了 ROWNUM,这可能导致意外结果。很少有任何理由使用 ROWNUM 代替 ROW_NUMBER() 或排名函数之一。
试试这个:
SELECT * FROM
(SELECT field1, field2 FROM fields order by field1 desc)
where rownum <= 5
另请查看此资源,以获取有关 rownum 如何工作的更详细说明。
Oracle 9i+ 提供分析功能:
所有都需要使用OVER
子句,它允许PARTITION BY
和ORDER BY
子句正确调优ROW_NUMBER
//返回的值RANK
。DENSE_RANK
在 9i 之前,唯一的选择是使用ROWNUM
- 顺便说一下比使用ROW_NUMBER
( link ) 更快。
在Oracle 12c中,这可以使用FETCH..FIRST
ROWS..ONLY
获取前 5 名最高薪水。
SELECT *
FROM EMPLOYEES
ORDER BY SALARY DESC
FETCH FIRST 5 ROWS ONLY;
Select emp_id , salary from employees
Order by salary desc
Limit 5;