第 3 课
JOIN 与查询结构
有意识地使用 JOIN,并理解查询结构如何影响结果行。
JOIN 用来把多张表中的行关联起来。在应用开发中,它常出现在实体关系里:订单属于用户,评论属于文章,发票属于账户。
SELECT users.email, orders.total
FROM users
JOIN orders ON orders.user_id = users.id
WHERE orders.status = 'paid';
关键是 ON 条件。它告诉数据库两边的行如何对应。如果条件错误或缺失,结果可能膨胀成远超预期的行数。
INNER JOIN 与 LEFT JOIN
JOIN 通常表示 inner join:只保留两边都匹配的行。
LEFT JOIN 会保留左表的所有行,即使右表没有匹配:
SELECT users.email, orders.id
FROM users
LEFT JOIN orders ON orders.user_id = users.id;
它适合“即使用户没有订单也要显示”的场景,但右表字段可能变成 NULL。
重复行往往是查询结构问题
如果一个用户有五个订单,users JOIN orders 后,这个用户就会出现五行。这不是数据库错误,而是关系结构的自然结果。
看到类似重复行时,先问:
- 这是不是一对多关系?
- 这里是否应该聚合?
- JOIN 条件是否漏掉了复合键的一部分?
- 是否把右表过滤条件写到
WHERE中,让LEFT JOIN实际变成了 inner join?
关键结论
把 JOIN 看成“结果行如何被放大或保留”的规则。格式化能让 JOIN 块变清楚,但你仍然要判断关系基数:一对一、一对多、可选关系。
使用 SQL 格式化工具 先看清每个 JOIN 和 ON 条件,再评审结果行。