【问题标题】:ORACLE sql query for getting top 3 salaries rownum greater thanORACLE sql查询获取前3名工资rownum大于
【发布时间】:2012-04-26 22:03:52
【问题描述】:

我想编写一个查询来显示获得前 3 名薪水的员工

  SELECT *
    FROM (SELECT salary, first_name
            FROM employees
        ORDER BY salary desc)
   WHERE rownum <= 3;

但我不明白如何为嵌套查询计算此 rownum 这行得通吗?如果有问题,请让我理解:

SELECT *
  FROM (SELECT salary, first_name 
          FROM employees
      ORDER BY salary )
 WHERE rownum >= 3;

我浏览了这个链接Oracle/SQL: Why does query "SELECT * FROM records WHERE rownum >= 5 AND rownum <= 10" - return zero rows,但它再次指向一个链接,它没有给出答案

【问题讨论】:

  • 你的数据结构是什么?不,我不能你了解任何事情(其他人也不能)。

标签: sql oracle


【解决方案1】:

a_horse_with_no_name 的回答很好,
但只是为了让您了解为什么您的第一个查询有效而您的第二个查询无效:

当您使用子查询时,Oracle 不会神奇地使用 子查询 的 rownum,它只是获取排序的数据,因此它会相应地给出 rownum,第一个匹配条件的行仍然获得 rownum 1,依此类推。这就是为什么您的第二个查询仍然不返回任何行的原因。

如果要限制起始行,需要保留子查询的rownum,即:

SELECT *
FROM (SELECT * , rownum rn
  FROM (SELECT salary, first_name
          FROM employees
      ORDER BY salary ) )sq
WHERE sq.rn >= 3;

但正如 a_horse_with_no_name 所说,还有更好的选择......

编辑:为了让事情更清楚,看看这个查询:

with t as (
select 'a' aa, 4 sal from dual
union all
select 'b' aa, 1 sal from dual
union all
select 'c' aa, 5 sal from dual
union all
select 'd' aa, 3 sal from dual
union all
select 'e' aa, 2 sal from dual
order by aa
)
select sub.*, rownum main_rn 
  from (select t.*, rownum sub_rn from t order by sal) sub 
 where rownum < 4

注意sub rownum和main rownum的区别,看哪个用于criteria

【讨论】:

  • @ABCade...一个疑问...当子查询被触发..它将所有数据(假设10行)作为结果集对象,rownum从1分配到10(按降序排列薪金)..................................................现在我们得到了所有的表数据......当我们触发外部查询......使用 rownum>=3 时,输出应该将结果返回为除 3 个最高薪水行之外的所有其他行
  • 不,它是外部查询的 rownum,因此它不会匹配任何行(每个都会得到 rownum 1),这就是为什么在示例中我必须保留子查询的 rownum(别名为 rn )
【解决方案2】:

查询的“rownum”是在应用到结果的排序依据之前分配的。所以 rownumw 42 可能会成为第一行。

一般来说,您需要使用内部查询中的 rownum 来限制您的整体输出。这在手册中有很好的解释:

http://docs.oracle.com/cd/E11882_01/server.112/e26088/pseudocolumns009.htm#i1006297

我更喜欢使用 row_number(),因为您可以更好地控制排序,而且它是适用于大多数现代 DBMS 的标准功能:

SELECT *
FROM (
  SELECT salary, 
         first_name, 
         row_number() over (order by salary) as rn
  FROM employees
)
WHERE rn <= 3
ORDER BY salary;

您应该了解,在这种情况下,派生表只需要能够对生成的rn 列应用条件。它不能避免“rownum 问题”,因为row_number() only 的值取决于over(...) 部分中指定的顺序(它独立于应用于查询本身的任何排序)

请注意,这不会返回薪水相同但仍低于前三名的员工。在这种情况下,使用dense_rank() 可能更合适。

【讨论】:

  • @a_horse_with_no_name... 在上面提到的代码中... rank() 函数是否也将与 row_number() 一样工作{我个人第一次听说函数 row_number}跨度>
  • @jain007:rank() 和 row_number() 之间的区别在于,如果 salaray 相同,rank() 将为两行分配相同的值,而 row_number() 将分配两个不同的值被生成。试试看。手册中的更多信息:docs.oracle.com/cd/E11882_01/server.112/e26088/…
【解决方案3】:

如果您想选择薪水最高的 3 人.. 或许您应该考虑使用分析.. 类似的东西

SELECT *
FROM (
    SELECT salary, first_name, dense_rank() over(order by salary desc) sal_rank
    FROM employees 
)
WHERE  sal_rank <= 3

即所有拥有第三高(排名)工资金额(或更多)的人

与使用普通 rownum 相比,这样做的好处是,如果您有多个薪水相同的人,他们都会被退回。

【讨论】:

    【解决方案4】:

    打印第 5 高薪水的最简单方法。

    SELECT MIN(SALARY) FROM (SELECT SALARY FROM EMPLOYEES ORDER BY DESC) WHERE ROWNUM BETWEEN 1 AND 5 
    

    如果你想打印第 3 或第 4 高薪水,那么只需更改最后一个值。(意味着使用 3 或 4 而不是 5,你将获得第 3 或第 4 高薪水)。

    SELECT MIN(SALARY) FROM (SELECT SALARY FROM EMPLOYEES ORDER BY DESC) WHERE ROWNUM BETWEEN 1 AND 4
    
    SELECT MIN(SALARY) FROM (SELECT SALARY FROM EMPLOYEES ORDER BY DESC) WHERE ROWNUM BETWEEN 1 AND 3
    

    【讨论】:

      【解决方案5】:

      选择 EMPNO, 萨尔, (从测试 E 中选择总和(E.SAL),其中 E.EMPNO

      【讨论】:

        【解决方案6】:

        在 oracle 中查找前 3 名员工返回所有字段详细信息的最简单方法:

        SELECT *
        FROM (
            SELECT * FROM emp  
              ORDER BY sal DESC)
        WHERE rownum <= 3 ;
        

        【讨论】:

          【解决方案7】:
          select * 
          from (
              select emp.*, 
                     row_number() over(order by sal desc)r 
              from emp
          ) 
          where r <= 3;
          

          【讨论】:

          • 欢迎来到 Stackoverflow。如果您可以在 SQL 中添加一些描述,以帮助其他人更好地理解答案,那就太好了。
          【解决方案8】:
          SELECT Max(Salary)
          FROM Employee
          WHERE Salary < (SELECT Max(salary) FROM employee WHERE Salary NOT IN (SELECT max(salary) FROM employee))
          ORDER BY salary DESC;
          

          【讨论】:

          • 如果面试官告诉你不使用rownum、limit和ranl你必须找到第三高的薪水,那么你可以试试这个
          • 您好,欢迎您,请将您的评论放在您刚刚在上面写的答案中,而不是添加到 cmets 中。阅读How to Answer了解更多详情
          猜你喜欢
          • 1970-01-01
          • 2013-10-22
          • 1970-01-01
          • 2021-12-26
          • 2011-04-04
          • 1970-01-01
          • 1970-01-01
          • 2020-05-11
          • 2020-06-25
          相关资源
          最近更新 更多