繁体   English   中英

什么是简单的SQL查询来选择收入第二高的人的ID

[英]What is a simple SQL query to select the ID of a person with the SECOND highest salary

如果我有关系:员工(身份证,薪水)。 最简单的SQL查询来选择收入第二高的人的ID。

我知道如何使用以下方法选择最高薪水:

SELECT MAX(salary)
FROM employee
WHERE salary < (SELECT MAX(salary)
FROM employee);

但是您将如何选择该人员的ID,并仅显示薪水第二高的人员的ID(不使用LIMIT)。

最佳答案取决于薪水指数的存在。 我已经设置了一个sqlfiddle ,它在表中加载了10万行。

使用索引,我的答案将是:

SELECT * FROM employee ORDER BY salary DESC LIMIT 1 OFFSET 1;

这是最简单,最短和最干净的一种。 由于它使用向后索引扫描,因此也是最快的,只有40µs。 但是,如果有第二个位置的搭配,它将仅返回一行。

仍然具有索引,上面三个在子查询中带有max()的查询紧随其后。 Bob Jarvis的得分为100µs。

不幸的是,当postgres扫描整个索引时,戈登的window函数遇到了一个障碍(嗯,至少它没有进行排序):

Subquery Scan on e (cost=0.29..7518.27 rows=500 width=20) (actual time=0.042..137.810 rows=1 loops=1)
Filter: (e.seqnum = 2)
Rows Removed by Filter: 99999
-> WindowAgg (cost=0.29..6268.27 rows=100000 width=20) (actual time=0.029..121.445 rows=100000 loops=1)
-> Index Scan Backward using emps_sal on employee e_1 (cost=0.29..4768.27 rows=100000 width=12)
 (actual time=0.022..54.861 rows=100000 loops=1)

这需要137毫秒,这相当长。 我相信根本原因是postgres将“ seqnum = 2”视为任何其他WHERE表达式,因此没有意识到它可以在第二行之后停止。 我们可以通过添加“ LIMIT 1”来微调它,在这种情况下,它不会在第二行之后停止,并且仅需70µs,因此非常快。

现在,没有索引...

我对ORDER BY的查询进行了排序,但是它是postgres的光荣的top-n堆排序,速度很快:34毫秒。

Gordon't window功能无法进行完整排序,这需要108毫秒。

Bob的查询没有排序,但是它扫描表3次:84 ms。

我将使用row_number()rank() ,具体取决于您所说的第二高薪水:

SELECT e.*
FROM (SELECT e.*, RANK() OVER (ORDER BY salary DESC) as seqnum
      FROM employee e
     ) e
WHERE seqnum = 2;

如果您想使用查询-这似乎更复杂-您可以使用子查询:

SELECT e.*
FROM employee e
WHERE e.salary = (SELECT MAX(e2.salary)
                  FROM employee e2
                  WHERE e2.salary < (SELECT MAX(e3.salary)
                                     FROM employee e3
                                    )
                 );

很高兴看到SQL在过去30年中取得了一些进步。

SELECT *
FROM employee
WHERE salary = (
  SELECT max(salary)
  FROM employee
  WHERE salary != (
    SELECT max(salary)
    FROM employee
  )
);
SELECT ID
  FROM EMPLOYEE
  WHERE SALARY = (SELECT MAX(salary) AS SECOND_HIGHEST_SALARY
                    FROM employee
                    WHERE salary < (SELECT MAX(salary) AS HIGHEST_SALARY
                                      FROM employee)

这将为您提供所有薪水第二高的员工的ID。 如果只希望一位雇员在外部查询上使用SELECT MIN(ID)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM