我想计算Oracle中最高的第n个工资。我已经完成了我的解决方案,但在谷歌上我发现一个查询做了同样的事情。
这是查询
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子句,它将选择高于外部查询工资的工资。内部和外部查询之间的运算符如何相等以及如何进行比较。
有没有人可以帮助我理解这个查询在后端技术上是如何工作的?
答案 0 :(得分:2)
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
例如假设表中只有3行:
ID Name Birth Orig_Salary
2 John 15-JUL-97 2341
3 Joe 25-JAN-86 4321
4 Tom 13-SEP-06 5413
主查询将查看第一行 - &gt; 2 John 15-JUL-97 2341&lt; ---,子查询将返回2,因为工资4321(emp2.orig_salary)和5413(emp2.orig_salary)大于2341(emp1.orig_salary)
然后主查询将查看第二行 - &gt; 3 Joe 25-JAN-86 4321&lt; ---,并且子查询将返回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
然后将子查询返回的值与where条件n-1进行比较,如果满足条件,则检索该行。
答案 1 :(得分:1)
无需了解该查询。正确的表述是:
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;
从关系数据库不像现在这样强大的时代开始,使用相关子查询是一个令人愉快的时代错误。这具有历史意义。