【发布时间】:2011-01-19 09:20:02
【问题描述】:
如何编写一个查询,其中只返回选定数量的行以及最高或最低列值。
即一份收入最高的 5 名员工的报告?
【问题讨论】:
如何编写一个查询,其中只返回选定数量的行以及最高或最低列值。
即一份收入最高的 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() 或排名函数之一。
【讨论】:
QUALIFY ... <= 5 而不是将其包装在另一个选择中。
http://download.oracle.com/docs/cd/E12032_01/doc/epm.921/html_ir_studio/ir_studio-15-36.html
试试这个:
SELECT * FROM
(SELECT field1, field2 FROM fields order by field1 desc)
where rownum <= 5
还可以查看this resource,了解有关 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;
【讨论】:
LIMIT 不是 oracle 语法。但它在其他一些数据库中使用,例如 mysql/mariadb/postgresql/sqlite 语法,每 stackoverflow.com/a/595155/44862