sql - 左连接中“where”null和“on”之间的区别
问题描述
有人可以向我解释为什么
select "talent".* from "talent"
left join "push" on "push"."talentId" = "talent"."id"
where ("push"."offerId" = '403' or "push"."offerId" is null)
产生的结果少于
select "talent".* from "talent"
left join "push" on "push"."talentId" = "talent"."id" and "push"."offerId" in ('403')
在我看来,它应该归结为相同的结果,但事实并非如此,而且我不确定我错过了什么。
第一个不包含push
表中没有条目的行。
我希望他们被or "push"."offerId" is null
.
编辑:
这是一个例子:
人才表
+----+------+
| id | name |
+----+------+
| 1 | John |
| 2 | Bob |
| 3 | Jack |
+----+------+
推桌
+----+----------+---------+
| id | talentId | offerId |
+----+----------+---------+
| 1 | 1 | 403 |
| 2 | 1 | 42 |
| 3 | 2 | 123 |
| 3 | 2 | 456 |
+----+----------+---------+
有了这些数据,带有where
子句的查询只返回
+----+------+---------+
| id | name | offerId |
+----+------+---------+
| 1 | John | 403 |
+----+------+---------+
而on
有条件的返回所有想要的行
+----+------+---------+
| id | name | offerId |
+----+------+---------+
| 1 | John | 403 |
| 2 | Bob | null |
| 3 | Jack | null |
+----+------+---------+
解决方案
不同之处在于当有匹配但在另一行时。最好用一个小例子来说明这一点。
考虑:
t1:
x y
1 abc
1 def
2 xyz
t2:
x y
1 def
然后left join
版本返回所有三行t1
:
select *
from t1 left join
t2
on t1.x = t2.x and t1.y = t2.y;
where
子句版本中的过滤:
select *
from t1 left join
t2
on t1.x = t2.x
where t2.y = 'abc' or t2.y is null;
只返回一行。返回的行是1
/ abc
。 x = 2
匹配t2
. 所以,t2.y
不是null
。它也不'abc'
是。所以它被过滤掉了。
这是一个 db<>fiddle。
推荐阅读
- android - Android 导航和活动中的单独动态功能
- vue.js - Vue/Vuex/Axios,已分配计算属性,但没有设置器
- java - 使用接口 Java 的简单报警系统
- python - 基于 Loss 和 IoU 如何知道何时停止训练 CNN 模型?
- mysql - 为什么我的 mysql 日期查询没有带回它应该是的所有日期
- php - 如何仅显示所选类别的子类别
- node.js - 如何跨 node.js 服务器保存数据?
- javascript - 在表中如何使用角度 9 中的按钮启用和禁用引导复选框?
- rust - 如何解决 IOerror (windows power shell)
- firebase - 必须向 Text 小部件颤振提供非空字符串?