牛客网——SQL218 获取所有非manager员工当前的薪水情况

发布时间 2023-08-28 17:56:46作者: 莫离y

描述

有一个员工表employees简况如下:

emp_no birth_date first_name last_name gender hire_date
10001 1953-09-02 Georgi Facello M 1986-06-26
10002 1964-06-02 Bezalel Simmel F 1996-08-03

有一个,部门员工关系表dept_emp简况如下:

emp_no dept_no from_date to_date
10001 d001 1986-06-26 9999-01-01
10002 d001 1996-08-03 9999-01-01

有一个部门经理表dept_manager简况如下:

dept_no emp_no from_date to_date
d001 10002 1996-08-03 9999-01-01

有一个薪水表salaries简况如下:

emp_no salary from_date to_date
10001 88958 1986-06-26 9999-01-01
10002 72527 1996-08-03 9999-01-01

获取所有非manager员工薪水情况,给出dept_no、emp_no以及salary,以上例子输出:

dept_no emp_no salary
d001 10001 88958

示例1:

drop table if exists  `dept_emp` ; 
drop table if exists  `dept_manager` ; 
drop table if exists  `employees` ; 
drop table if exists  `salaries` ; 
CREATE TABLE `dept_emp` (
`emp_no` int(11) NOT NULL,
`dept_no` char(4) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`));
CREATE TABLE `dept_manager` (
`dept_no` char(4) NOT NULL,
`emp_no` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`));
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));
INSERT INTO dept_emp VALUES(10001,'d001','1986-06-26','9999-01-01');
INSERT INTO dept_emp VALUES(10002,'d001','1996-08-03','9999-01-01');
INSERT INTO dept_manager VALUES('d001',10002,'1996-08-03','9999-01-01');
INSERT INTO employees VALUES(10001,'1953-09-02','Georgi','Facello','M','1986-06-26');
INSERT INTO employees VALUES(10002,'1964-06-02','Bezalel','Simmel','F','1996-08-03');
INSERT INTO salaries VALUES(10001,88958,'1986-06-26','9999-01-01');
INSERT INTO salaries VALUES(10002,72527,'1996-08-03','9999-01-01');

输出:

d001|10001|88958

我的解题思路:

  • 根据部门经理表找出所有经理的emp_no,使用子查询+not in 筛选出所有不是manager的emp_no
  • 再用内连接得到相应信息
select 
    de.dept_no as dept_no,
    t1.emp_no as emp_no,
    s.salary as salary
from (
select 
    emp_no
from employees
where emp_no not in (select distinct emp_no from dept_manager) 
) t1
inner join dept_emp de on t1.emp_no = de.emp_no
inner join salaries s on t1.emp_no = s.emp_no
where de.to_date = '9999-01-01'
;

更加优秀解题思路:

不使用not in

  • 找出所有非manger的emp_no,这里通过差集实现

    select t1.emp_no
    from employees t1
    left join dept_manager t2 on t1.emp_no = t2.emp_no
    where t2.emp_no is null
    ;
    
  • 再通过上表的 emp_no 去连接 dept_emp 和 salaries,找出对应的 dept_no 和 salary

  • 注意 salaries 的 to_date='9999-01-01'

select t4.dept_no, t3.emp_no, t5.salary
from(
 select t1.emp_no
 from employees t1
 left join dept_manager t2 on t1.emp_no = t2.emp_no
 where t2.emp_no is null
) t3
inner join dept_emp t4 on t3.emp_no = t4.emp_no
inner join salaries t5 on t3.emp_no = t5.emp_no
where t5.to_date='9999-01-01'
;