简体   繁体   English

ORACLE SQL查询获取前3名薪水rownum大于

[英]ORACLE sql query for getting top 3 salaries rownum greater than

I want to write a query to display employees getting top 3 salaries 我想写一个查询以显示获得前三名薪水的员工

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

But I dont understand how this rownum is calculated for the nested query will this work or if it has problem ,request you to please make me understand: 但是我不明白如何为嵌套查询计算该rownum是否可以正常工作,或者如果遇到问题,请您让我理解:

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

I went through this link Oracle/SQL: Why does query "SELECT * FROM records WHERE rownum >= 5 AND rownum <= 10" - return zero rows ,but it again points to a link, which does not gives the answer 我通过了Oracle / SQL链接:为什么查询“ SELECT * FROM records where rownum> = 5 AND rownum <= 10”-返回零行 ,但它再次指向链接,但没有给出答案

a_horse_with_no_name's answer is a good one, a_horse_with_no_name的答案很不错,
but just to make you understand why you're 1st query works and your 2nd doesn't: 但是只是为了让您理解为什么您是第一个查询而第二个却不行:

When you use the subquery, Oracle doesn't magically use the rownum of the subquery , it just gets the data ordered so it gives the rownum accordingly, the first row that matches criteria still gets rownum 1 and so on. 当您使用子查询时,Oracle不会神奇地使用子查询的rownum,它只会获取有序的数据,因此它会相应地提供rownum,符合条件的第一行仍将获得rownum 1,依此类推。 This is why your 2nd query still returns no rows. 这就是为什么第二个查询仍然不返回任何行的原因。

If you want to limit the starting row, you need to keep the subquery's rownum, ie: 如果要限制起始行,则需要保留子查询的rownum,即:

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

But as a_horse_with_no_name said there are better options ... 但是正如a_horse_with_no_name所说,还有更好的选择...

EDIT: To make things clearer, look at this query: 编辑:为了使事情更清楚,请看以下查询:

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

note the difference between the sub rownum and the main rownum, see which one is used for criteria 请注意子行和主行之间的区别,请参阅哪一个用于标准

The "rownum" of a query is assigned before an order by is applied to the result. 查询的“行编号” 将order by应用于结果之前已分配。 So the rownumw 42 could wind up being the first row. 因此,行编号42可能会成为第一行。

Generally speaking you need to use the rownum from the inner query to limit your overall output. 一般来说,您需要使用内部查询中的rownum来限制整体输出。 This is very well explained in the manual: 手册对此进行了很好的解释:

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

I prefer using row_number() instead, because you have much better control over the sorting and additionally it's a standard feature that works on most modern DBMS: 我更喜欢使用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;

You should understand that the derived table in this case is only necessary to be able to apply a condition on the generated rn column. 您应该理解,在这种情况下,派生表仅是必需的,以便能够对生成的rn列应用条件。 It's not there to avoid the "rownum problem" as the value of row_number() only depends on the order specifiy in the over(...) part (it is independent of any ordering applied to the query itself) 不能避免“行数问题”,因为row_number()的值取决于over(...)部分中指定的顺序(它独立于应用于查询本身的任何顺序)

Note this would not return employees that have the same salary and would still fall under the top three. 请注意,这将不会返回具有相同薪水但仍属于前三名的员工。 In that case using dense_rank() is probably more approriate. 在这种情况下,使用dense_rank()可能更合适。

if you want to select the people with the top 3 salaries.. perhaps you should consider using analytics.. something more like 如果您想选择薪水最高的3个人。也许您应该考虑使用分析工具。

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

ie ALL people with the 3rd highest(ranked) salary amount(or more) 即所有薪水金额排名第三(或更高)的人

the advantage of this over using plain rownum is if you have multiple people with the same salary they will all be returned. 与使用普通rownum相比,此方法的优势在于,如果您有多个薪水相同的人,他们将全部返回。

Easiest way to print 5th highest salary. 最简单的打印第五高薪水的方法。

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

according to same if u want to print 3rd or 4th highest salary then just chage last value.(means instead of 5 use 3 or 4 you will get 3rd or 4th highest salary). 根据相同的方法,如果您想打印第三或第四高薪,则只需更改最后一个值即可。(平均值代替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

SELECT EMPNO,SAL(从E.EMPNO <= T.EMPNO的测试中选择SUM(E.SAL),R_SAL FROM(SELECT EMPNO,EMPNO的测试订单中的SAL)T

Easiest way to find the top 3 employees in oracle returning all fields details: 返回所有字段详细信息的最容易找到oracle前3名员工的方法:

SELECT *
FROM (
    SELECT * FROM emp  
      ORDER BY sal DESC)
WHERE rownum <= 3 ;
select * 
from (
    select emp.*, 
           row_number() over(order by sal desc)r 
    from emp
) 
where r <= 3;
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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM