SQL JOIN
SQL JOIN 在查询阶段按条件组合多张表的行;INNER JOIN 只保留匹配,LEFT JOIN 保留左表并用 NULL 补右侧缺失。
#concept
#growing
#backend
#sql
#database
[!info] related notes
- 所属 MOC: database-moc
- 前置概念: one-to-many-relationship、foreign-key
- 并列概念: sql-group-by、sql-aggregate-functions
- 易混淆概念:
- 关系笔记: sql-join-group-by-and-aggregation、sql-on-vs-where-in-outer-join
SQL JOIN
一句话定义
JOIN 用连接条件把多张表的行组合成一个查询结果集;它读取和组合数据,不会把原表永久合并。
核心机制
SELECT a.title, u.name
FROM articles a
JOIN users u
ON a.user_id = u.id;
ON a.user_id = u.id 定义哪些行彼此匹配。最常见的是沿外键到主键连接,但 JOIN 本身并不要求数据库必须定义外键。
INNER JOIN
INNER JOIN 只保留两边都匹配成功的组合:
users ∩ articles
如果某个 User 没有 Article,它不会出现在结果里。
LEFT JOIN
LEFT JOIN 保留左表的所有行;右表没有匹配时,右侧列为 NULL:
SELECT u.name, a.title
FROM users u
LEFT JOIN articles a
ON a.user_id = u.id;
适合“所有用户,包括没有文章的用户”这类需求。
行数为什么会放大
JOIN 不是“一行对一行”。如果 User 1 匹配 3 个 Article,查询结果会产生 3 行 User 1。后续统计通常要再配合 GROUP BY 或在应用层重新组装结构。
FK 与 JOIN 的边界
FOREIGN KEY:约束持久化数据的引用合法性。JOIN:查询时组合已经存在的数据。
可以没有外键照样 JOIN,也可以定义外键但完全不执行 JOIN。
常见风险
LEFT JOIN后在WHERE里过滤右表字段,可能把NULL行过滤掉,使结果表现得像 INNER JOIN。- 多个 1:N 同时 JOIN 可能产生笛卡尔式行数放大,聚合前要明确粒度。
- JOIN 是否快取决于数据量、过滤选择性、索引、统计信息和执行计划,不是“用了 JOIN 就慢”。