我有两个mysql表: join_test_l
以及 join_test_r
.
加入测试:
+------+------+
| ca | cb |
+------+------+
| a | s |
| b | s |
| c | d |
| d | NULL |
+------+------+
加入测试:
+------+------+
| cc | cb |
+------+------+
| a | NULL |
| b | s |
| c | d |
| d | NULL |
+------+------+
当我试图用左连接和 <>
左表过滤器:
select * from join_test_l as l left join join_test_r as r on l.cb=r.cb where l.ca<>'c';
+------+------+------+------+
| ca | cb | cc | cb |
+------+------+------+------+
| a | s | b | s |
| b | s | b | s |
| d | NULL | NULL | NULL |
+------+------+------+------+
排在哪里 l.ca
是 null
留下了。当我试图用左连接和 <>
右表上的筛选器:
select * from join_test_l as l left join join_test_r as r on l.cb=r.cb where r.cc<>'c';
+------+------+------+------+
| ca | cb | cc | cb |
+------+------+------+------+
| a | s | b | s |
| b | s | b | s |
+------+------+------+------+
所有的行在哪里 r.cc
是 null
也被移除。
能解释一下吗?我的意思是为什么结果集中的空值会被 <>
条款?
2条答案
按热度按时间7bsow1i61#
你需要把逻辑移到
WHERE
条款ON
条款:这里的问题是
WHERE
正在从结果集中筛选记录。另一方面,通过将逻辑移到联接,我们保留左表中的每条记录join_test_l
. 然后,那些没有加入任何东西的记录就会null
中的每一列join_test_r
.n53p2ov02#
重新
<>
&null
x<>y
是true
什么时候x
(在正常意义上)不等于y
and x is not null and y is not null
. 它是false
什么时候x
在正常意义上等于y
and x is not null and y is not null
. 否则从技术上来说unknown
,但这恰好被当作null
按运算符/语法is
.大多数sql运算符都是这样的--当每个参数
is not null
,和unknown
(被当作null
)否则。sql运算符不是具有相同名称的普通关系运算符或数学运算符;他们对待(价值观)unknown
&null
特别是(这么说null
不是一个模糊的值是没有帮助的。)关于mysql 8.0参考手册12.3.2比较函数和运算符中的“正常意义上的相等”一词:
比较运算的结果是
1
(TRUE
),0
(FALSE
),或NULL
.<=>
NULL
-安全平等。此运算符执行与=
运算符,但返回1
而不是NULL
如果两个操作数都是NULL
,和0
而不是空值NULL
. 这个<=>
运算符等价于标准sqlIS NOT DISTINCT FROM
接线员。注意
on
&where
返回条件计算结果为的行true
. 当约束不计算为false
.重新
left join
on
&where
了解左/右联接返回的内容:内部联接行加上由null扩展的不匹配的左/右表行。full join返回内部联接行,并将所有不匹配的左表行和右表行合并为null。始终知道作为外部连接的一部分,您需要什么样的内部连接。一个where或on,它要求一个可能为null的扩展列在外部联接on删除任何由null扩展的行之后不为null,即只留下内部联接行,即“将外部联接转换为内部联接”。你有这个。阅读SQLDBMS文档。