模块课程(2/4)
将所有内容保留在左侧:LEFT JOIN
上一课中的 INNER JOIN 有一个重要的副作用:它
删除不匹配的行。如果员工没有部门
(department_id 是 NULL),它们从结果中消失。
有时这就是你想要的。但通常情况并非如此:在人力资源报告中
有必要看到所有员工,包括那些没有部门的员工,
并知道他们是谁。这就是 LEFT JOIN 的用途(完整的,LEFT OUTER JOIN)。
它是如何运作的
SELECT columns
FROM table_a
LEFT JOIN table_b ON table_a.x = table_b.y;用英语阅读:“保留table_a的所有行;对于每一行尝试
附加 table_b 中的一行;如果没有匹配项,请填写以下列
table_b 与 NULL"。
关键字是**LEFT**:它的意思是“左表”,即写的那个
在 FROM 之后。它的所有行都永远存在。
-- All employees, including those without a department:
SELECT e.first_name,
e.last_name,
d.name AS dipartimento
FROM employees AS e
LEFT JOIN departments AS d ON e.department_id = d.id;在我们的数据集中,此查询返回 10 行(每行一名员工)。安德里亚
Costa 具有 department_id = NULL,与 dipartimento = NULL 一起出现
而不是消失。
查找“不匹配”的行
一个非常有用的结果:通过在列上使用 IS NULL 进行过滤
在右侧表中,您准确地找到了不匹配的行:
-- Orphan employees: no department assigned
SELECT e.first_name, e.last_name
FROM employees AS e
LEFT JOIN departments AS d ON e.department_id = d.id
WHERE d.id IS NULL;这个技巧在现实世界中一直在使用:“找到我的订单,没有 客户", "没有评论的产品", "从未登录过的用户 在“.
尝试一下
返回未分配部门的员工的名字 (first_name) 和姓氏 (last_name)。一行或多行,两列。
显示提示
使用 d.id IS NULL 完成 WHERE — 您需要 LEFT JOIN 未找到匹配部门的行。
3 次尝试后可用的解决方案
复习练习
列出所有部门 (departments.name) 及其旁边的员工人数,还包括没有员工的部门(显示 0)。提示:从部门开始,与员工进行 LEFT JOIN,然后进行 GROUP BY + COUNT。
显示提示
当没有匹配项时,使用 COUNT(e.id)(而不是 COUNT(*))计算 0:由于 LEFT JOIN 行包含 NULL,因此 COUNT(*) 会计算 1。
3 次尝试后可用的解决方案