LEFT JOIN 中 `ON` 与 `WHERE` 过滤条件的区别分析
LEFT JOIN 中 ON
与 WHERE
过滤条件的区别分析
假设有两表:
表 a
x y z 1 2 4 2 3 5 表 b
x z 1 4 2 3
SQL1: a LEFT JOIN b ON a.x = b.x AND b.z = 3
逻辑:
- 左连接过程中,同时匹配
a.x = b.x
且b.z = 3
的行。 - 结果特点:
- 保留表
a
所有行(无论是否匹配到b
)。 b
表的匹配行需满足b.z = 3
,否则填充NULL
。
- 保留表
结果示例:
1 | a.x | a.y | a.z | b.x | b.z |
SQL2: a LEFT JOIN b ON a.x = b.x WHERE b.z = 3
逻辑:
- 先执行左连接(仅匹配
a.x = b.x
,不限制b.z
)。 - 在连接后的结果中,过滤出
b.z = 3
的行。
副作用:
WHERE
条件会排除b
表未匹配的行(即b.z
为NULL
的行)。- 最终结果等价于内连接 (
INNER JOIN
)。
结果示例:
1 | a.x | a.y | a.z | b.x | b.z |
关键区别总结
差异点 | SQL1 (ON ... AND b.z=3 ) |
SQL2 (WHERE b.z=3 ) |
---|---|---|
保留 a 所有行 |
是(右表未匹配则填充 NULL ) |
否(WHERE 过滤掉 NULL ,等效内连接) |
过滤时机 | 连接时过滤右表 (b ) |
连接后过滤整个结果集 |
结果范围 | 显示 a 表全部数据,右表可能为 NULL |
仅显示同时满足 a.x=b.x 和 b.z=3 的行 |
结论
- 若需保留
a
表所有行并筛选b
的匹配条件,用 SQL1(条件在ON
中)。 - 若仅需
a
和b
同时满足x
相等且b.z=3
的行,用 SQL2(实际效果等价于INNER JOIN
)。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 牛蛙JUN!