使用 sql 计算第 n 个最高薪水

calculate highest nth salary using sql

我想计算 Oracle 中第 n 个最高薪水。我已经完成了我的解决方案,但在 google 上我发现一个查询在做同样的事情。

这里是查询

SELECT *
FROM Employee Emp1
WHERE (N - 1) = (SELECT COUNT(DISTINCT(Emp2.orig_salary))
                    FROM Employee Emp2
                    WHERE emp2.orig_salary > emp1.orig_salary)

数据

   ID   Name    Birth       Orig_Salary
    2   John    15-JUL-97   2341    
    3   Joe     25-JAN-86   4321    
    4   Tom     13-SEP-06   2413    
    5   Jane    17-APR-05   7654    
    6   James   18-JUL-04   5679    
    7   Jodd    20-JUL-03   5438    
    8   Joke    01-JAN-02   8765    
    9   Jack    29-AUG-01   7896

我无法理解这个查询。 在 运行 内部查询之后,它总是会给我计数 8 之后,它会转到 where 子句,在那里它会选择高于外部查询薪水的薪水。相等运算符在内部查询和外部查询之间如何工作以及比较是如何进行的。

任何人都可以帮助我理解这个查询在后端技术上是如何工作的吗?

无需理解该查询。正确的表述是:

SELECT Emp1.*
FROM (SELECT Emp1.*, DENSE_RANK() OVER (ORDER BY Emp2.orig_salary) as seqnum
      FROM Employee Emp1
     ) Emp1
WHERE seqnum = <n>;

这提供了员工的详细信息。如果你只想要工资:

SELECT orig_salary
FROM (SELECT Emp1.*, DENSE_RANK() OVER (ORDER BY Emp2.orig_salary) as seqnum
      FROM Employee Emp1
     ) Emp1
WHERE seqnum = <n> AND rownum = 1;

我应该注意到一个更简单的版本是:

select distinct orig_salary
from employees
order by orig_salary desc
offset <n - 1>
fetch first 1 row only;

在关系数据库还没有像现在这样强大的时代,为此使用相关子查询是一种令人愉快的不合时宜的做法。它具有历史意义。

SELECT *
FROM Employee Emp1
WHERE (N - 1) = (SELECT COUNT(DISTINCT(Emp2.orig_salary))
                FROM Employee Emp2  <--- cartesian product with same table
                WHERE emp2.orig_salary > emp1.orig_salary)  <---- but  do the cartesian product only if line of salary of emp 2 is greater than the current line of Emp1 'salary 

例如假设 table 中只有 3 行:

身份证姓名出生Orig_Salary

2   John    15-JUL-97   2341    
3   Joe     25-JAN-86   4321    
4   Tom     13-SEP-06   5413 

主查询将查看第一行 --> 2 John 15-JUL-97 2341 <---,子查询将 return 2 因为工资 4321 (emp2.orig_salary)和 5413 (emp2.orig_salary) 大于 2341 (emp1.orig_salary)

然后主查询将查看第二行 --> 3 Joe 25-JAN-86 4321 <---,子查询将 return 1 因为工资 5413 (emp2.orig_salary ) 大于 2341 (emp1.orig_salary)

当我说子查询时,它是

=(SELECT COUNT(DISTINCT(Emp2.orig_salary))
                 FROM Employee Emp2  <--- cartesian product with same table
                WHERE emp2.orig_salary > emp1.orig_salary)

主要查询是

SELECT *
FROM Employee Emp1
WHERE 

然后将子查询中的 returned 值与 where 条件 n-1 进行比较,如果满足条件,则检索该行。