SQL中的第n个薪水
我试图理解下面的查询,它是如何工作的SQL中的第n个薪水,sql,oracle,subquery,greatest-n-per-group,Sql,Oracle,Subquery,Greatest N Per Group,我试图理解下面的查询,它是如何工作的 SELECT * FROM Employee Emp1 WHERE (N-1) = ( SELECT COUNT(DISTINCT(Emp2.Salary)) FROM Employee Emp2 WHERE Emp2.Salary > Emp1.Salary ) 假设我有5不同的薪水,并希望获得3最高的薪水。那么内部查询将首先运行
SELECT *
FROM Employee Emp1
WHERE (N-1) = (
SELECT COUNT(DISTINCT(Emp2.Salary))
FROM Employee Emp2
WHERE Emp2.Salary > Emp1.Salary
)
假设我有5
不同的薪水,并希望获得3
最高的薪水。那么内部查询将首先运行,然后是外部查询
我弄不清楚它是如何在sql引擎中完成的。我很想知道。因为如果其3rd
最大,则3-1=2
,因此2
也需要与内部计数匹配。内部计数是如何操作的
有人能解释一下它是如何工作的吗 子查询是相关子查询,因此从概念上讲,它对外部查询中的每一行执行一次(数据库优化分开)。。它所做的是计算有多少员工的工资高于外部查询中该行的工资:如果有两名员工的工资较高,则您知道外部查询中当前行的员工的工资第三高
另一种表达方式是使用行号()
select *
from (
select
e.*,
row_number() over(order by salary desc) rn
from employee e
) t
where rn = 3
根据您希望如何处理重复项,densite\u rank()
也可能是一个选项
SELECT * FROM (SELECT EMP.ID,RANK() OVER (ORDER BY SALARY DESC) AS NOS FROM EMPLOYEE) T WHERE T.NOS=3
然后从中选择一个具有任何所需等级的 运行此查询时更容易理解:
select e1.*,
(select count(distinct e2.salary)
from employee e2
where e2.salary > e1.salary) as n
from employee e1
这是我的示例表:
create table employee(salary) as (
select * from table(sys.odcinumberlist(1500, 1200, 1400, 1500, 1100)));
所以我的输出是:
SALARY N
---------- ----------
1500 0
1200 2
1400 1
1500 0
1100 3
正如您所看到的,对于每一行,子查询统计的薪资都大于当前行中的薪资。例如,对于1400人,有一个明显更高的工资(1500)。1500在我的表中出现两次,但distinct
使其计数一次。所以1400是第二顺序
您的查询将此计数移动到中的部分,并与所需值进行比较。我们必须减去一,因为对于最高工资,没有更高的值,对于第二工资,一行等等
这是用于查找此类值的方法之一,较新的Oracle版本引入了分析函数(秩、行数、密集秩),从而消除了使用子查询进行此类操作的需要。它们更快、更高效。对于您的查询,densite\u rank()
将非常有用。因此,在这种情况下,外部查询首先运行,然后是内部查询……这样说是否正确。。?理想情况下,内部查询首先运行。@Maria:的确如此。子查询引用了一个来自外部查询的列,因此它不可能首先执行。我可能会使用densite\u rank()
而不是row\u number()
@a\u horse\u with\u no\u name:OP没有真正告诉他们如何处理重复项,所以我选择了row\u number()
。我编辑了我的答案以提及densite\u rank()
。DISTINCT
不是一个函数。跳过那些多余的括号以编写更清晰的代码,即只需执行选择计数(DISTINCT Emp2.Salary)
。我将使用子查询返回第三大的DISTINCT Salary。可能是接受答案的idsa。