题解 | #获取每个部门中当前员工薪水最高的相关信息#

获取每个部门中当前员工薪水最高的相关信息

http://www.nowcoder.com/practice/4a052e3e1df5435880d4353eb18a91c6

题解

SELECT t_dep_maxsal.dep_no,s.emp_no,t_dep_maxsal.dep_maxsal FROM(
    SELECT dep_no,MAX(sal) dep_maxsal FROM (
    SELECT de.dept_no dep_no,de.emp_no emp_no,salary sal
    FROM dept_emp de
    JOIN salaries s
    ON de.emp_no=s.emp_no
    ) t_dep_emp_sal
    GROUP BY t_dep_emp_sal.dep_no
)t_dep_maxsal
LEFT JOIN salaries s
ON t_dep_maxsal.dep_maxsal=s.salary
AND s.emp_no IN( SELECT emp_no FROM dept_emp WHERE dept_no=t_dep_maxsal.dep_no)
ORDER BY dep_no ASC;

测试数据与题解详细说明

测试数据:

#测试数据1
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_emp VALUES(10003,'d002','1996-08-09','9999-01-01');
INSERT INTO dept_emp VALUES(10004,'d003','1996-08-08','9999-01-01');
INSERT INTO dept_emp VALUES(10005,'d003','1996-08-07','9999-01-01');
INSERT INTO dept_emp VALUES(10006,'d003','1996-08-07','9999-01-01');

INSERT INTO salaries VALUES(10001,78958,'2002-06-22','9999-01-01');
INSERT INTO salaries VALUES(10002,82527,'2001-08-02','9999-01-01');
INSERT INTO salaries VALUES(10003,92527,'2001-08-07','9999-01-01');
INSERT INTO salaries VALUES(10004,82527,'2001-08-08','9999-01-01');
INSERT INTO salaries VALUES(10005,53527,'2001-08-06','9999-01-01');
INSERT INTO salaries VALUES(10006,93527,'2001-08-06','9999-01-01');

#测试数据1-表数据
SELECT * FROM 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 |
|  10003 | d002    | 1996-08-09 | 9999-01-01 |
|  10004 | d003    | 1996-08-08 | 9999-01-01 |
|  10005 | d003    | 1996-08-07 | 9999-01-01 |
|  10006 | d003    | 1996-08-07 | 9999-01-01 |
+--------+---------+------------+------------+
6 ROWS IN SET (0.00 sec)

SELECT * FROM salaries;
+--------+--------+------------+------------+
| emp_no | salary | from_date  | to_date    |
+--------+--------+------------+------------+
|  10001 |  78958 | 2002-06-22 | 9999-01-01 |
|  10002 |  82527 | 2001-08-02 | 9999-01-01 |
|  10003 |  92527 | 2001-08-07 | 9999-01-01 |
|  10004 |  82527 | 2001-08-08 | 9999-01-01 |
|  10005 |  53527 | 2001-08-06 | 9999-01-01 |
|  10006 |  93527 | 2001-08-06 | 9999-01-01 |
+--------+--------+------------+------------+
6 ROWS IN SET (0.00 sec)

#测试数据2
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_emp VALUES(10003,'d002','1996-08-09','9999-01-01');
INSERT INTO dept_emp VALUES(10004,'d003','1996-08-08','9999-01-01');
INSERT INTO dept_emp VALUES(10005,'d003','1996-08-07','9999-01-01');
INSERT INTO dept_emp VALUES(10006,'d003','1996-08-07','9999-01-01');
INSERT INTO dept_emp VALUES(10007,'d002','1996-08-07','9999-01-01');
INSERT INTO dept_emp VALUES(10008,'d002','1996-08-07','9999-01-01');

INSERT INTO salaries VALUES(10001,78958,'2002-06-22','9999-01-01');
INSERT INTO salaries VALUES(10002,82527,'2001-08-02','9999-01-01');
INSERT INTO salaries VALUES(10003,92527,'2001-08-07','9999-01-01');
INSERT INTO salaries VALUES(10004,82527,'2001-08-08','9999-01-01');
INSERT INTO salaries VALUES(10005,53527,'2001-08-06','9999-01-01');
INSERT INTO salaries VALUES(10006,93527,'2001-08-06','9999-01-01');
INSERT INTO salaries VALUES(10007,94527,'2001-08-06','9999-01-01');
INSERT INTO salaries VALUES(10008,94527,'2001-08-06','9999-01-01');

#测试数据2-表数据
SELECT * FROM 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 |
|  10003 | d002    | 1996-08-09 | 9999-01-01 |
|  10004 | d003    | 1996-08-08 | 9999-01-01 |
|  10005 | d003    | 1996-08-07 | 9999-01-01 |
|  10006 | d003    | 1996-08-07 | 9999-01-01 |
|  10007 | d002    | 1996-08-07 | 9999-01-01 |
|  10008 | d002    | 1996-08-07 | 9999-01-01 |
+--------+---------+------------+------------+
8 ROWS IN SET (0.00 sec)

SELECT * FROM salaries;
+--------+--------+------------+------------+
| emp_no | salary | from_date  | to_date    |
+--------+--------+------------+------------+
|  10001 |  78958 | 2002-06-22 | 9999-01-01 |
|  10002 |  82527 | 2001-08-02 | 9999-01-01 |
|  10003 |  92527 | 2001-08-07 | 9999-01-01 |
|  10004 |  82527 | 2001-08-08 | 9999-01-01 |
|  10005 |  53527 | 2001-08-06 | 9999-01-01 |
|  10006 |  93527 | 2001-08-06 | 9999-01-01 |
|  10007 |  94527 | 2001-08-06 | 9999-01-01 |
|  10008 |  94527 | 2001-08-06 | 9999-01-01 |
+--------+--------+------------+------------+
8 ROWS IN SET (0.00 sec)

题解详细说明:

★★★使用测试数据1
1.1、连接查询-得到部门id与员工id及其工资
SELECT de.dept_no,de.emp_no,salary
FROM dept_emp de
JOIN salaries s
ON de.emp_no=s.emp_no;
+---------+--------+--------+
| dept_no | emp_no | salary |
+---------+--------+--------+
| d001    |  10001 |  78958 |
| d001    |  10002 |  82527 |
| d002    |  10003 |  92527 |
| d003    |  10004 |  82527 |
| d003    |  10005 |  53527 |
| d003    |  10006 |  93527 |
+---------+--------+--------+
6 ROWS IN SET (0.00 sec)

1.2、子查询+分组查询-将1.1查询结果作为临时表(from子查询),以部门id分组,得到各部门最高工资
SELECT dep_no,MAX(sal) FROM (
    SELECT de.dept_no dep_no,de.emp_no emp_no,salary sal
    FROM dept_emp de
    JOIN salaries s
    ON de.emp_no=s.emp_no
) t_dep_emp_sal
GROUP BY t_dep_emp_sal.dep_no;
+--------+----------+
| dep_no | MAX(sal) |
+--------+----------+
| d001   |    82527 |
| d002   |    92527 |
| d003   |    93527 |
+--------+----------+
3 ROWS IN SET (0.00 sec)

1.3、子查询+连接查询-把1.2查询结果作为临时表(from子查询),连接薪资表,得到与最高薪资相同的员工id(这时部门id与员工id有不匹配的数据)
SELECT t_dep_maxsal.dep_no,s.emp_no,t_dep_maxsal.dep_maxsal FROM(
    SELECT dep_no,MAX(sal) dep_maxsal FROM (
    SELECT de.dept_no dep_no,de.emp_no emp_no,salary sal
    FROM dept_emp de
    JOIN salaries s
    ON de.emp_no=s.emp_no
    ) t_dep_emp_sal
    GROUP BY t_dep_emp_sal.dep_no
)t_dep_maxsal
LEFT JOIN salaries s
ON t_dep_maxsal.dep_maxsal=s.salary;
+--------+--------+------------+
| dep_no | emp_no | dep_maxsal |
+--------+--------+------------+
| d001   |  10002 |      82527 |
| d001   |  10004 |      82527 |
| d002   |  10003 |      92527 |
| d003   |  10006 |      93527 |
+--------+--------+------------+
4 ROWS IN SET (0.00 sec)

1.4、在1.3的基础上继续筛选; 条件:员工需是该部门的员工  最后再按部门id升序排序
SELECT t_dep_maxsal.dep_no,s.emp_no,t_dep_maxsal.dep_maxsal FROM(
    SELECT dep_no,MAX(sal) dep_maxsal FROM (
    SELECT de.dept_no dep_no,de.emp_no emp_no,salary sal
    FROM dept_emp de
    JOIN salaries s
    ON de.emp_no=s.emp_no
    ) t_dep_emp_sal
    GROUP BY t_dep_emp_sal.dep_no
)t_dep_maxsal
LEFT JOIN salaries s
ON t_dep_maxsal.dep_maxsal=s.salary
AND s.emp_no IN( SELECT emp_no FROM dept_emp WHERE dept_no=t_dep_maxsal.dep_no)
ORDER BY dep_no ASC;
+--------+--------+------------+
| dep_no | emp_no | dep_maxsal |
+--------+--------+------------+
| d001   |  10002 |      82527 |
| d002   |  10003 |      92527 |
| d003   |  10006 |      93527 |
+--------+--------+------------+
3 ROWS IN SET (0.00 sec)

★★★使用测试数据2
数据说明:同一个部门有两个员工薪资相同且是部门最高薪资
SELECT t_dep_maxsal.dep_no,s.emp_no,t_dep_maxsal.dep_maxsal FROM(
    SELECT dep_no,MAX(sal) dep_maxsal FROM (
    SELECT de.dept_no dep_no,de.emp_no emp_no,salary sal
    FROM dept_emp de
    JOIN salaries s
    ON de.emp_no=s.emp_no
    ) t_dep_emp_sal
    GROUP BY t_dep_emp_sal.dep_no
)t_dep_maxsal
LEFT JOIN salaries s
ON t_dep_maxsal.dep_maxsal=s.salary
AND s.emp_no IN( SELECT emp_no FROM dept_emp WHERE dept_no=t_dep_maxsal.dep_no)
ORDER BY dep_no ASC;
+--------+--------+------------+
| dep_no | emp_no | dep_maxsal |
+--------+--------+------------+
| d001   |  10002 |      82527 |
| d002   |  10007 |      94527 |
| d002   |  10008 |      94527 |
| d003   |  10006 |      93527 |
+--------+--------+------------+
4 rows in set (0.00 sec)
题目要求是获取每个部门中当前员工薪水最高的相关信息,所以要把部门2这两个员工信息都查询出来,符合题意。

关于分组查询(分组函数)的一些问题

  1. 分组函数在使用的时候必须先进行分组,然后才能用,如果没有对数据进行分组,整张表默认为一组。
  2. 和分组函数一同查询的字段要求是group by后的字段(在一条select语句当中,如果有group by语句的话,select后面只能跟:参加分组的字段,以及分组函数,其它的一律不能跟)
    SELECT AVG(salary),employee_id FROM employees GROUP BY employee_id; 可执行
    SELECT AVG(salary),employee_id,job_id FROM employees GROUP BY employee_id;该语句mysql中可以执行,但无意义;oracle中执行报错;
全部评论
可以啊
点赞 回复 分享
发布于 2022-09-24 17:22 上海

相关推荐

05-12 18:24
长安大学 UE4
因为是家里第一代大学生,报专业报学校都没人可以指导,只能自己看着来毕业找工作,父母只知道考公务员啊考教师啊,丝毫不考虑难度我说要去大城市打工才行,小县城对学历没有需求,开的工资都很低,两三千养活不了的结果都不同意我去大城市,觉得北上广深远,不稳定,一年到头不着家,养这么大孩子算白养了要我怎么办,不考公不考编就是死路一条呗,出去打工就是不孝呗可是考公考编也好难,考上也是小职员,到时候又变成了家里第一代体制内了,不还是样样靠自己有时候很羡慕同学,要去大城市打拼,家里都很支持去看看外面的世界也羡慕同学父母都是体制内的,考上还有所依靠家里没有办法给予帮助,简直是进入死胡同一样
Two_Shadow:你先拿到offer,路是自己走的,你真去了谁拦得住你呢,不用给自己扣帽子,我也是我家第一代大学生啊,农村人,高考96个志愿我就填50多个计算机,爸妈让我填满保底我说我不,我就学计算机,上大学了让我考研我说我不考,我就喜欢干活,现在签了offer,他们也释怀,不回家就努力提升自己,就往家里打钱,就开视频,还能怎么样呢,路是自己走的,他们只是希望你能走得好一点,但大部分父母,尤其是农村父母根本帮不了你什么,难道你就不走路了吗,希望能骂醒你,不要想太多做太少。
点赞 评论 收藏
分享
秋盈丶:后续:我在宿舍群里和大学同学分享了这事儿,我好兄弟气不过把他挂到某脉上了,10w+阅读量几百条评论,直接干成精品贴子,爽
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务