如何获得一组第二高的值?

How to Get Set of Second Highest Values?

假设我有以下 table:

    employee_id    salary
    34             100
    22             49
    19             49
    29             30
    17             22

并且我想return工资第二高的员工集合(当有联系时),如下:

   employee_id    salary
   22             49
   19             49

我该怎么做?

使用DENSE_RANK:

SELECT employee_id, salary
FROM
(
    SELECT employee_id, salary, DENSE_RANK() OVER (ORDER BY salary DESC) dr
    FROM yourTable
) t
WHERE dr = 2;

您可以使用嵌套查询。

采取的步骤:

  1. 获取所有薪水值(排序并获得第二大值):

SELECT salary FROM employee GROUP BY 1 ORDER BY 1 DESC limit 1 OFFSET 1;

或可以写成:

SELECT salary FROM employee GROUP BY employee_id ORDER BY employee_id DESC limit 1 OFFSET 1;

现在在员工内部使用查询 table

SELECT * FROM employee where salary=(SELECT salary FROM employee GROUP BY 1 ORDER BY 1 DESC limit 1 OFFSET 1);

这也可以使用下面的查询来完成,

场景一:输出两条记录

WITH employee
AS (
SELECT 34 emp_id, 100 rate FROM DUAL
UNION
SELECT 22 emp_id, 49 rate FROM DUAL
UNION
SELECT 19 emp_id, 49 rate FROM DUAL
UNION
SELECT 29 emp_id, 30 rate FROM DUAL
UNION
SELECT 17 emp_id, 22 rate FROM DUAL),
emp_rate_cnt AS 
(SELECT rownum rown, rate, same_rate_count
   FROM (SELECT rate, count(1) same_rate_count
           FROM employee
          GROUP BY rate
          ORDER BY rate DESC))
SELECT *
  FROM employee a
 WHERE exists (SELECT 1
                 FROM emp_rate_cnt b
                WHERE b.rate = a.rate
                  AND b.rown = 2
                  AND b.same_rate_count > 1);

场景二:输出无记录

WITH employee
AS (
SELECT 34 emp_id, 100 rate FROM DUAL
UNION
SELECT 22 emp_id, 49 rate FROM DUAL
UNION
SELECT 19 emp_id, 50 rate FROM DUAL
UNION
SELECT 29 emp_id, 30 rate FROM DUAL
UNION
SELECT 17 emp_id, 22 rate FROM DUAL),
emp_rate_cnt AS 
(SELECT rownum rown, rate, same_rate_count
   FROM (SELECT rate, count(1) same_rate_count
           FROM employee
          GROUP BY rate
          ORDER BY rate DESC))
SELECT *
  FROM employee a
 WHERE exists (SELECT 1
                 FROM emp_rate_cnt b
                WHERE b.rate = a.rate
                  AND b.rown = 2
                  AND b.same_rate_count > 1);

我希望这是最简单的。使用 rownum,因为它是 Oracle。

SELECT t.employee_id, t.salary
FROM
(
    SELECT distinct employee_id, salary, rownum as row from 
    FROM yourTable order by salary desc
) t
WHERE t.row = 2;