Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL中的第n个薪水_Sql_Oracle_Subquery_Greatest N Per Group - Fatal编程技术网

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。