试图找到一个Oracle查询来找到第n个最高薪水,其中一个是经验最丰富的

问题描述 投票:0回答:3

我需要找到薪水第三高的人的名字

该表格如下:

Name       Salary    Experience
-------------------------------
Den        11000       114
Gerald     11000       148
Ellen      11000       174
Eleni      10500       149
Clara      10500       162
Janette    10000       156 
Peter      10000       150
Hermann    10000       204
Harrison   10000       169

我需要找到具有最大经验和第3个最高工资标准的人的姓名。

很明显,第三高的薪水是10000,而薪水第三高的人的最大经验是赫尔曼,exp为204。

我有查询找到第三高薪:

select name, salary, experience 
from sal s1 
where 3 - 1 = (select count(distinct salary) 
               from sal s2 
               where s2.salary > s1.salary);

但是这个查询返回4行,我需要知道如何在同一查询中进一步过滤它以找到exp为204的Hermann。

sql oracle greatest-n-per-group
3个回答
0
投票

此查询使用ROWNUM和MAX来查找正确的行。在最里面的子查询中,为每个工资级别检索最大经验,按工资降序排序,然后在外部子查询中添加行号,并将其与原始表连接以查找正确的行

SELECT s.name, s.salary, s.experience
FROM sal s
JOIN (SELECT s2.*, ROWNUM rnum
      FROM (SELECT salary, max(experience) AS m_exp
            FROM sal 
            GROUP BY salary
            ORDER BY salary DESC) s2) s3 ON s3.salary = s.salary AND 
                                            s3.m_exp = s.experience AND 
                                            rnum = 3 

3
投票

使用DENSE_RANK解析函数找到第3个最高工资和ROW_NUMBER(或RANKDENSE_RANK)解析函数和PARTITION BY子句,以找到每个工资的最高经验。这只需要一次表/索引扫描。

Oracle安装程序:

CREATE TABLE table_name ( Name, Salary, Experience ) AS
SELECT 'Den',      11000, 114 FROM DUAL UNION ALL
SELECT 'Gerald',   11000, 148 FROM DUAL UNION ALL
SELECT 'Ellen',    11000, 174 FROM DUAL UNION ALL
SELECT 'Eleni',    10500, 149 FROM DUAL UNION ALL
SELECT 'Clara',    10500, 162 FROM DUAL UNION ALL
SELECT 'Janette',  10000, 156 FROM DUAL UNION ALL
SELECT 'Peter',    10000, 150 FROM DUAL UNION ALL
SELECT 'Hermann',  10000, 204 FROM DUAL UNION ALL
SELECT 'Harrison', 10000, 169 FROM DUAL

查询:如果您想找到“在第3个最高工资标准中具有最大经验的人”:

SELECT Name, Salary, Experience
FROM   (
  SELECT t.*,
         DENSE_RANK() OVER ( ORDER BY Salary DESC ) AS s_rank,
         ROW_NUMBER() OVER ( PARTITION BY Salary ORDER BY Experience DESC )
           AS Exp_rownum
  FROM   table_name t
)
WHERE s_rank = 3
AND   Exp_rownum = 1;

如果您将ROW_NUMBER()解析函数换成RANK()DENSE_RANK(),那么如果它们与第3个最高工资标准中的联合最高经验相关联,则会返回多个人。

输出:

NAME    | SALARY | EXPERIENCE
:------ | -----: | ---------:
Hermann |  10000 |        204

查询:如果您想找到“具有最大经验且(也)在第3个最高工资标准中的人”:

只需执行上面的查询并删除PARTITION BY子句。

SELECT Name, Salary, Experience
FROM   (
  SELECT t.*,
         DENSE_RANK() OVER ( ORDER BY Salary DESC ) AS s_rank,
         ROW_NUMBER() OVER ( ORDER BY Experience DESC ) AS Exp_rownum
  FROM   table_name t
)
WHERE s_rank = 3
AND   Exp_rownum = 1;

输出:

(注意:如果Herman的经验是173,那么这将不会返回任何排,因为Ellen将拥有最高的经验,但她不会在第三高薪水中,而Herman将排在第三高的薪水范围,但只有第二高经验。)

NAME    | SALARY | EXPERIENCE
:------ | -----: | ---------:
Hermann |  10000 |        204

db <>小提琴here


0
投票

您不查询体验。所以你要添加一个where子句:

select name, salary, experience 
from sal s1 
where 3 - 1 = (select count(distinct salary) 
               from sal s2 
               where s2.salary > s1.salary)
  and experience = (select max(experience) from sal)

UPDATE

替代方案(第三高薪内的最大经验)应为:

select name, salary, experience 
from sal s1 
where 3 - 1 = (select count(distinct salary) 
               from sal s2 
               where s2.salary > s1.salary)
  and experience = (select max(experience)  from sal s3 
                    where 3 - 1 = (select count(distinct salary) 
                                   from sal s4 
                                   where s4.salary > s3.salary)
                    )
© www.soinside.com 2019 - 2024. All rights reserved.