SQL Server:显示具有Max&的员工Min薪酬部门明智吗?(查看截图)任何更好的解决方案

时间:2014-02-04 09:24:44

标签: sql sql-server select inner-join

以下是我的解决方案。任何更好的方法请建议
从Oracle数据库迁移的SQL Server中的HR数据库生成的解决方案

这是输出
Screenshot

这是表结构 Table Structure

SELECT e.DEPARTMENT_ID,d.MaxSalary,es.FIRST_NAME,dm.MinSalary,esd.FIRST_NAME
FROM 
    EMPLOYEES e
    JOIN (  SELECT department_id, MAX(salary) MaxSalary 
            FROM EMPLOYEES 
            GROUP BY DEPARTMENT_ID) d
    ON e.DEPARTMENT_ID=d.DEPARTMENT_ID
    JOIN (  SELECT first_name,DEPARTMENT_ID 
            FROM EMPLOYEES ess 
            WHERE SALARY IN (SELECT MAX(salary) FROM EMPLOYEES WHERE DEPARTMENT_ID=ess.DEPARTMENT_ID)) es
    ON e.DEPARTMENT_ID=es.DEPARTMENT_ID
    JOIN (  SELECT department_id,min(salary) MinSalary 
            FROM EMPLOYEES group by DEPARTMENT_ID) dm
    ON e.DEPARTMENT_ID=dm.DEPARTMENT_ID
    JOIN (  SELECT first_name,DEPARTMENT_ID
            FROM EMPLOYEES ess 
            WHERE SALARY in (SELECT MIN(salary) FROM EMPLOYEES WHERE DEPARTMENT_ID=ess.DEPARTMENT_ID )) esd
    ON e.DEPARTMENT_ID=esd.DEPARTMENT_ID
GROUP BY 
    e.DEPARTMENT_ID
    ,d.MaxSalary
    ,es.FIRST_NAME
    ,dm.MinSalary
    ,esd.FIRST_NAME

3 个答案:

答案 0 :(得分:2)

你的查询看起来很复杂,我不是SQL专家,我确​​信有更多知识的人会对此有所改进,但这是我的工作(下面的代码没有检查语法/错误,可能只应该使用作为指导方针):

首先,我会将您的查询简化为仅在单个查询中包含每个部门的MINMAX工资:

SELECT
    [DEPARTMENT_ID] = e.DEPARTMENT_ID
    ,[MaxSalary] = MAX(e.salary)
    ,[MinSalary] = MAX(e.salary)
FROM
    EMPLOYEES e
GROUP BY
    e.DEPARTMENT_ID

此时您将获得如下结果:

DEPARTMENT_ID    MaxSalary    MinSalary
10               4400         4400
20               13000        6000
30               11000        2500
...              ...          ...

从这里你可以像以前一样使用子查询(虽然我认为这通常是低效的):

SELECT
    aggr.[DEPARTMENT_ID]
    , [FIRST_NAME] = maxEmp.[FIRST_NAME]
    , aggr.[MaxSalary]
    , [FIRST_NAME] = minEmp.[FIRST_NAME]
    , aggr.[MinSalary]
FROM
    (   SELECT
            [DEPARTMENT_ID] = e.[DEPARTMENT_ID]
            ,[MaxSalary] = MAX(e.[salary])
            ,[MinSalary] = MAX(e.[salary])
        FROM
            EMPLOYEES e
        GROUP BY
            e.[DEPARTMENT_ID]
    ) aggr
    INNER JOIN EMPLOYEES maxEmp ON maxEmp.[salary] = aggr.[MaxSalary] AND maxEmp.[DEPARTMENT_ID] = aggr.[DEPARTMENT_ID]
    INNER JOIN EMPLOYEES minEmp ON minEmp.[salary] = aggr.[MinSalary] AND minEmp.[DEPARTMENT_ID] = aggr.[DEPARTMENT_ID]

或者您可以使用HAVING,如下所示:

SELECT
    [DEPARTMENT_ID] = e.[DEPARTMENT_ID]
    , [FIRST_NAME] = maxEmp.[FIRST_NAME]
    , [MaxSalary] = MAX(e.[salary])
    , [FIRST_NAME] = minEmp.[FIRST_NAME]
    , [MinSalary] = MAX(e.[salary])
FROM
    EMPLOYEES e
    INNER JOIN EMPLOYEES maxEmp ON maxEmp.[DEPARTMENT_ID] = e.[DEPARTMENT_ID]
    INNER JOIN EMPLOYEES minEmp ON minEmp.[DEPARTMENT_ID] = e.[DEPARTMENT_ID]
GROUP BY
    e.[DEPARTMENT_ID]
    , maxEmp.[salary]
    , maxEmp.[FIRST_NAME]
    , maxEmp.[salary]
    , minEmp.[FIRST_NAME]
HAVING
    maxEmp.[salary] = MAX(e.[salary])
    AND maxEmp.[salary] = MIN(e.[salary])

我不相信这两者都是一个完美的解决方案,但它可以起作用。我建议您使用您的结构和一些虚拟数据创建SQL Fiddle,以便人们更轻松地帮助您。与您的结果一样,如果有多名员工的最低或最高工资,它将返回多行。

答案 1 :(得分:0)

您可以使用两种方法

  1. 使用带有连接的dense_rank()

选择 a.department,a.max_sal_emp, a.max_salary,b.min_sal_emp,b.min_salary from

(select department,first_name as max_sal_emp,salary as max_salary from (select department,first_name,salary,dense_rank() over (partition by department order by salary desc) as max_sal_rank from Employees)e where max_sal_rank=1) a

加入

(select department,first_name as min_sal_emp,salary as min_salary from (select department,first_name,salary,dense_rank() over (partition by department order by pay) as min_sal_rank from员工)e where min_sal_rank=1) b

a.department=b.department 按部门排序;

  1. 使用相关子查询

    选择department_id,first_name,salary from (select department_id,first_name,salary,(select max(salary) as max_dept_sal from雇员e2 where e2.department_id = e1.department_id),select min(salary) min_Dept_Sal from雇员e2 where e2.department_id = e1.department_id) from雇员e1 ) e 其中薪水 = max_dept_sal 或薪水 = min_dept_sal 按department_id、salary desc排序

<块引用>
Expected O/p format:
dept_id first_name salary
1        aaa         10000
1        abc         2000
2        xxx         75000
2        xyz         32000

答案 2 :(得分:-1)

Select a. empid, a.ename, b.dept from employee inner join dept on a.deptid=b.deptid and a. empid in(


(select 
a.empid
rowumber () rank over partition by b.dept order by b.sal a desc
from
employee a
inner join
dept b  on a.deptno=b.deptno
where rank =1
union
select 
a.empid
rowumber ()  rank over partition by b.dept order by b.sal a asc
from
employee a
inner join
dept b   on a.deptno=b.deptno
where rank =1
)
)