LEFT JOIN 中 ONWHERE 过滤条件的区别分析

假设有两表:

  • 表 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
2
3
4
a.x | a.y | a.z | b.x | b.z
-----------------------------
1 | 2 | 4 | NULL| NULL -- b.z=4 不满足条件,填充NULL
2 | 3 | 5 | 2 | 3 -- 匹配成功

SQL2: a LEFT JOIN b ON a.x = b.x WHERE b.z = 3

逻辑:

  1. 先执行左连接(仅匹配 a.x = b.x,不限制 b.z)。
  2. 在连接后的结果中,过滤出 b.z = 3 的行。

副作用

  • WHERE 条件会排除 b 表未匹配的行(即 b.zNULL 的行)。
  • 最终结果等价于内连接 (INNER JOIN)。

结果示例:

1
2
3
a.x | a.y | a.z | b.x | b.z
-----------------------------
2 | 3 | 5 | 2 | 3 -- 仅保留满足 WHERE 条件的行

关键区别总结

差异点 SQL1 (ON ... AND b.z=3) SQL2 (WHERE b.z=3)
保留 a 所有行 是(右表未匹配则填充 NULL 否(WHERE 过滤掉 NULL,等效内连接)
过滤时机 连接时过滤右表 (b) 连接后过滤整个结果集
结果范围 显示 a 表全部数据,右表可能为 NULL 仅显示同时满足 a.x=b.xb.z=3 的行

结论

  • 若需保留 a 表所有行并筛选 b 的匹配条件,用 SQL1(条件在 ON 中)。
  • 若仅需 ab 同时满足 x 相等且 b.z=3 的行,用 SQL2(实际效果等价于 INNER JOIN)。