1. 题目
-
题目描述
获取所有非manager员工薪水情况,给出dept_no、emp_no以及salary -
表格
-
所需结果
2. 题解
思路:使用JOIN连接表格,进行行过滤和列合并。
进行条件过滤时,可以使用WHERE子查询 + IN
,也可以直接使用 LEFT JOIN + IS NULL
的方法。
这题有一个坑,先看错误解法:
# 方法一:JOIN
#(错误解法:多出的一个表格含有其它数据)
SELECT de.dept_no, e.emp_no, s.salary
FROM employees e
JOIN dept_emp de
ON e.emp_no = de.emp_no
LEFT JOIN dept_manager dm
ON de.dept_no = dm.dept_no
JOIN salaries s
ON e.emp_no = s.emp_no
WHERE dm.emp_no IS NULL
正确解法:
方法一:
这里使用的一个JOIN技巧就是通过LEFT JOIN + IS NULL
,来进行行筛选。
#方法一:正确解法(使用JOIN)
SELECT de.dept_no, de.emp_no, s.salary
FROM dept_emp de
JOIN salaries s
ON de.emp_no = s.emp_no
LEFT JOIN dept_manager dm
ON dm.emp_no = de.emp_no # 也可以使用另一个字段(dept_no):dm.dept_no = de.dept_no
WHERE dm.dept_no IS NULL
方法二:
子查询中使用IN进行条件筛选。
# 方法二:WHERE 子查询 + IN
SELECT dept_no, emp_no, salary
FROM dept_emp de
JOIN salaries s
ON de.emp_no = s.emp_no
WHERE de.emp_no NOT IN (SELEC emp_no
FROM dept_manager)
先找准已经养成了一个不好的习惯,遇到题目就用子查询,有点多此一举:
SELECT t.dept_no, t.emp_no, t.salary
FROM (SELECT de.emp_no, de.dept_no, s.salary
FROM dept_emp de
JOIN salaries s
ON de.emp_no = s.emp_no
WHERE de.to_date = '9999-01-01'
AND s.to_date = '9999-01-01'
AND de.emp_no NOT IN (SELECT emp_no FROM dept_manager)
) t
这里把”在职“这个条件也加上去了(题目没有显示给出)