17

您如何编写查询,其中仅返回选定数量的行以及最高或最低列值。

即 5 名最高薪员工的报告?

4

5 回答 5

26

最好的方法是使用分析函数 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() 或排名函数之一。

于 2010-02-21T17:59:17.840 回答
13

试试这个:

SELECT * FROM 
    (SELECT field1, field2 FROM fields order by field1 desc) 
where rownum <= 5

另请查看此资源,以获取有关 rownum 如何工作的更详细说明。

于 2010-02-21T17:46:20.190 回答
4

Oracle 9i+ 提供分析功能:

所有都需要使用OVER子句,它允许PARTITION BYORDER BY子句正确调优ROW_NUMBER//返回的值RANKDENSE_RANK

在 9i 之前,唯一的选择是使用ROWNUM- 顺便说一下比使用ROW_NUMBER( link ) 更快。

于 2010-02-21T19:17:53.167 回答
3

Oracle 12c中,这可以使用FETCH..FIRST ROWS..ONLY

获取前 5 名最高薪水。

 SELECT *
       FROM EMPLOYEES
   ORDER BY SALARY DESC
FETCH FIRST 5 ROWS ONLY;
于 2018-02-06T12:12:03.177 回答
-1
Select emp_id , salary from employees
  Order by salary desc
  Limit 5;
于 2018-09-25T05:12:26.763 回答