-- 表数据
table_1:
| A | B | C | D |
|-----|-----|-----|-----|
| c | d | 3 | 4 |
| a | b | 1 | 2 |
table_2:
| A | B | C | D |
|-----|-----|-----|-----|
| c | d | 2 | 4 |
| a | b | 1 | 3 |
-- 请写出以下两条SQL代码执行后的结果
-- 1.
select * from table_1 m left join table_2 n on m.A=n.A and m.B=n.B and n.C=1;
-- 2.
select * from table_1 m left join table_2 n on m.A=n.A and m.B=n.B where n.C=1;
得到的结果是:
-- 1.第一条SQL语句返回的结果
c d 3 4
a b 1 2 a b 1 3
-- 2.第二条SQL语句返回的结果
a b 1 2 a b 1 3
关键区别总结
-
ON中的条件(如第一条语句的
n.C=1
):
属于连接条件,不影响左表保留,仅决定右表是否匹配。若右表不匹配,左表数据仍保留(右表补NULL
)。 -
WHERE中的条件(如第二条语句的
n.C=1
):
是对连接后结果的全局过滤。若右表列为NULL
或不满足条件,整行被过滤(左表数据也可能丢失)。
其实,这类问题主要还是你的需求是什么,如果你只是想做关联,那就用第二种,一般这样相当于是筛选条件,会把所有符合的数据都去掉,左表也一样去除。而第一种其实就是保留主表不改变,加上右表做判断处理。
在工作中,原表与原表匹配关联的场景是会经常发生的。
常见应用场景
场景 | SQL模式 | 关键点 |
---|---|---|
数据历史版本比对 | 主表 LEFT JOIN 历史表 ON 版本条件 | 过滤条件放ON中保留主表数据 |
数据质量检查 | 主表 LEFT JOIN 规则表 ON 关联键 | WHERE检查IS NULL异常记录 |
缓慢变化维处理 | 当前表 LEFT JOIN 历史表 ON 代理键 | 使用生效日期范围条件 |
数据增量同步检测 | 新数据集 LEFT JOIN 旧数据集 | WHERE找差异记录 |
总之,明确区分ON和WHERE的使用场景
-
ON条件:用于定义表间关联逻辑,应包含表之间的关联键
-
WHERE条件:用于过滤最终结果集
-
右表过滤条件:
-
若需要保留左表所有记录 → 放ON子句
-
若需要过滤最终结果 → 放WHERE子句
-