简体   繁体   English

在mysql中获得每个人的第二高薪

[英]Get second highest salary for each person in mysql

We have table like below 我们有如下表

person_id  |    salary
   1       |     1500
   1       |     1000
   1       |      500
   2       |     2000
   2       |     1000
   3       |     3000
   3       |     2000
   4       |     3000
   4       |     1000

We want second highest salary for each person. 我们想要每个人第二高的薪水。 grouping by each person and get second highest salary for person. 按每个人分组,并获得第二高的薪水。 like below 像下面

person_id  |    salary
   1       |     1000
   2       |     1000
   3       |     2000
   4       |     1000

Thanks in advance :) 提前致谢 :)

By using aggregate function and self join you could do something like 通过使用聚合函数和自连接,您可以执行以下操作

select a.*
from demo a
left join demo b on a.person_id = b.person_id
group by a.person_id,a.salary
having sum(a.salary < b.salary) = 1 /* 0 for highest 1 for second highest 2 for third and so on ... */

or using complete case expression in sum 或使用完整的情况下表达sum

having sum(case when a.salary < b.salary then 1 else 0 end)  = 1

Demo 演示版

Note This doesn't handle ties like a person may have 2 same salary values, i assume each salary value for a person will be different from other salary values for a person to handle such case approach mentioned by @juergen d will work with additional case statement 注意:这不能处理像一个人可能具有两个相同的薪水值的联系,我假设一个人的每个薪水值都将不同于一个人的其他薪水值,以处理@juergen d提到的这种情况方法将适用于其他情况声明

Here is one way using exists and having clause 这是一种使用existshaving子句的方法

SELECT person_id,
       Max(salary)
FROM   Yourtable a
WHERE  EXISTS (SELECT 1
               FROM   Yourtable b
               WHERE  a.person_id = b.person_id
               HAVING ( a.salary < Max(b.salary)
                        AND Count(*) > 1 )
                       OR Count(Distinct salary) = 1)
GROUP  BY person_id 

Try 尝试

select t1.*
from your_table t1
join
(
    select person_id,
           @rank := case when person_id = @prevPersonId then @rank + 1 else 1 end as rank,
           @prevPersonId := person_id
    from your_table
    cross join (select @rank := 0, @prevPersonId := 0) r
    group by person_id
    order by person_id asc, salary desc
) t2 on t1.person_id = t2.person_id
where rank = 2

Another way around JOIN . 围绕JOIN另一种方法。

Query 询问

 select t1.`person_id`, max(coalesce(t2.`salary`, t1.`salary_1`)) as `salary_2` from(
   select `person_id`, max(`salary`) as `salary_1`
   from `your_table_name`
   group by `person_id`
) t1
left join `your_table_name` t2
on t1.`person_id` = t2.`person_id`
and t1.`salary_1` <> t2.`salary`
group by t1.`person_id`;

Find a sql fiddle demo here 在此处查找sql​​小提琴演示

You could also use 您也可以使用

select max(salary), person_id
from (select salary, person_id from demo 
      except 
      (select max(salary), person_id from demo group by person_id)) s
group by person_id

removing max salaries for each person from initial dataset and starting over. 从初始数据集中删除每个人的最高薪水,然后重新开始。

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

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