「这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战」。
Test 1
有一个员工表 employees 简况如下:
有一个部门领导表
dept_manager 简况如下:
请你找出所有非部门领导的员工
emp_no ,以上例子输出:
解题思路
(1) 查询的要求是不在 dept_manager 表中的 emp_no,使用 NOT IN + 子查询。MYSQL官方文档中提到 IN 使用时效率不高,推荐使用 EXISTS 或 JOIN。
SELECT emp_no
FROM employees
WHERE emp_no NOT IN(SELECT DISTINCT emp_no
FROM dept_manager)
(2) 使用 LEFT JOIN 来连接两个表,再筛选非 manager 的员工。
SELECT e.emp_no
FROM employees AS e LEFT JOIN dept_manager AS d
ON e.emp_no = d.emp_no
WHERE dept_no IS NULL
(3) 使用 NOT EXISTS + 子查询 的方式。
SELECT emp_no
FROM employees AS e
WHERE NOT EXISTS(SELECT *
FROM dept_manager AS d
WHERE e.emp_no = d.emp_no)
Test 2
有一个员工表 dept_emp 简况如下:
第一行表示为员工编号为
10001 的部门是 d001 部门。
有一个部门经理表 dept_manager 简况如下:
第一行表示为
d001 部门的经理是编号为 10002 的员工。
获取所有的员工和员工对应的经理,如果员工本身是经理的话则不显示,以上例子如下:
解题思路
考察知识点
INNER JOIN 内连接。
根据题中的要求,使用内连接的方式连接两张表,同时要求两表的部门编号 dept_no 要相同,但员工编号 emp_no 不能相同。
SELECT e.emp_no, m.emp_no AS manager
FROM dept_emp AS e INNER JOIN dept_manager AS m
ON e.dept_no = m.dept_no
WHERE e.emp_no <> m.emp_no
为何要这样?一步步看!
我们先获取两表 CROSS JOIN(笛卡尔积)的结果。
我们先指定连接条件为
e.dept_no = m.dept_no, 在这些记录中寻找部门号相同的员工。得到如下结果。
然后再指定
e.emp_no <> m.emp_no ,筛选员工编号不相等的员工信息,这样就去掉了员工的经理是他本身这种情况。结果如下。
当然 WHERE 与 ON 中的条件顺序可以颠倒,并不影响结果。