根据表格数据查找每个部门的第3个最高工资

时间:2017-09-22 19:27:23

标签: sql sql-server tsql

我需要找到3rd maximum salary中每个部门的员工的table。如果不存在3rd maximum salary,则显示2nd maximum salary。如果不存在2nd maximum salary,则找到highest salary。如何在sql-server

中实现此结果

table结构如下所示

create table employee1(empid int, empname varchar(10), deptid int, salary money)

insert into employee1
select 1,'a',1, 1000
union
select 1,'b',1, 1200 
union
select 1,'c',1, 1500 
union
select 1,'c',1, 15700 
union
select 1,'d',2, 1000 
union
select 1,'e',2, 1200 
union
select 1,'g',3, 1500 

我尝试了使用row_number函数获取每个类别的最高薪水的常用方法。

;with cte
as
( 
select ROW_NUMBER( ) over( partition by deptid order by salary) as id, * from employee1 
)
select * from cte

6 个答案:

答案 0 :(得分:3)

答案取决于你是否想要关系以及如何处理它们。如果你想要没有关系,即使一个员工与另一个员工联系也会成为下一个最高薪水,那么诀窍就是使用row_number,就像你所显示的那个只降低工资,然后使用另一个{{1}扭转它。如果您不想再次使用row_number,那么您也可以使用其他一些技术,但步骤1是找到最高步骤2是反转该顺序

row_number

根据您的评论更新为; WITH cteRankSalariesByDepartment AS ( SELECT * ,RowNum = DENSE_RANK() OVER (PARTITION BY deptid ORDER BY salary DESC) FROM employee1 ) , cteReverseRankHighestSalaries AS ( SELECT * ,RowNum2 = DENSE_RANK() OVER (PARTITION BY deptid ORDER BY RowNum DESC) FROM cteRankSalariesByDepartment WHERE RowNum <= 3 ) SELECT * FROM cteReverseRankHighestSalaries WHERE RowNum2 = 1 ,您只需使用它代替DENSE_RANK()即可获得您的联系。

答案 1 :(得分:3)

Select EmpID,empname,deptid,salary
 From (
Select *
      ,RN  = Row_Number() over (Partition By deptid Order By Salary)
      ,Cnt = sum(1) over (Partition By deptid)
 From  employee1
      ) A
 Where RN = case when Cnt<3 then Cnt else 3 end

返回

enter image description here

答案 2 :(得分:2)

只需查询需要计数和row_number,条件如下:

;with cte
as
( 
select ROW_NUMBER( ) over( partition by deptid order by salary desc) as id, 
    Cnt = count(*) over(partition by deptid), * from employee1 
)
select * from cte where ( cnt >= 3 and id = 3 )
or ( cnt < 3 and id = 1 )

答案 3 :(得分:1)

您可以尝试以下查询:

select * from 
(
select 
 empid, 
 empname ,
 deptid ,
 salary ,
 ROW_NUMBER( ) over( partition by deptid order by id desc) as rev_id
from
( 
select 
 ROW_NUMBER( ) over( partition by deptid order by salary) as id, 
 empid, 
 empname ,
 deptid ,
 salary 
from employee1 
)
t where id<=3 
)t where rev_id=1

working demo

答案 4 :(得分:1)

您可以使用;with cte as ( select ROW_NUMBER( ) over( partition by deptid order by salary) as id, * from employee1 ) --get the 3rd highest select * from cte where id = 3 union --get the highest / max select c.* from cte c --this determines the highest which salary for each dept inner join (select deptid, max(id) id from cte group by deptid) x on x.deptid = c.deptid and x.id = c.id --this limits it on depts that aren't in the list in the first part of the query where c.deptid not in (select deptid from cte where id = 3)

object BnBSolver[S<:BnBState]{
  def solve(states: Seq[S], best_state:Option[S]): Option[S] = if (states.isEmpty) best_state else
     val next_state = states.head
     /* compare to best state, etc... */
     val new_states = new_branches ++ states.tail
     solve(new_states, new_best_state)
}

class BnBState[F<:Formula](clauses:F, assigned_variables) {
  def cost: Int

  def branches: Seq[BnBState] = {
    val ll = clauses.pick_variable
    List(
      BnBState(clauses.assign(ll), ll :: assigned_variables), 
      BnBState(clauses.assign(-ll), -ll :: assigned_variables)
    )
  }
}

case class Formula[F<:Formula[F]](clauses:List[List[Int]]) {
    def assign(ll: Int) :F = 
       Formula(clauses.filterNot(_ contains ll)
                      .map(_.filterNot(_==-ll))))

}

答案 5 :(得分:-1)

为了增加你的问题,我在第三位增加了两名薪水相同的员工。

要得到这个,你需要第一个密集的部门工资。在您需要反转l工资等级并获得职位1

之后

试试吧

    DECLARE @employee1 TABLE 
      ( 
         empid   INT, 
         empname VARCHAR(10), 
         deptid  INT, 
         salary  MONEY 
      ) 

    INSERT @employee1 Values 
    (1,'a',1, 1000  )
,(1,'b',1, 1200 )
,(2,'bb',1, 1200 )
,(1,'c',1, 1500 )
,(3,'ccc',1, 1500 )
,(1,'c',1, 15700) 
,(1,'d',2, 1000 )
,(1,'e',2, 1200 )
,(1,'g',3, 1500 ) 

    WITH cte_rank 
         AS (SELECT Dense_rank() 
                      OVER ( 
                        partition BY deptid 
                        ORDER BY salary) SalaryRank, 
                    * 
             FROM   @employee1), 
         cte_final 
         AS (SELECT Dense_rank() 
                      OVER ( 
                        partition BY deptid 
                        ORDER BY salaryrank DESC) SalaryRankReverse, 
                    * 
             FROM   cte_rank 
             WHERE  salaryrank <= 3) 
    SELECT * 
    FROM   cte_final 
    WHERE  salaryrankreverse = 1 

结果

SalaryRankReverse    SalaryRank           empid       empname    deptid      salary
-------------------- -------------------- ----------- ---------- ----------- ---------------------
1                    3                    1           c          1           1500.00
1                    3                    3           ccc        1           1500.00
1                    2                    1           e          2           1200.00
1                    1                    1           g          3           1500.00