MySQL left join: null 元素被 where 过滤
MySQL left join: null elements be filtered by where
我有 2 个 MySQL table:join_test_l
和 join_test_r
。
join_test_l:
+------+------+
| ca | cb |
+------+------+
| a | s |
| b | s |
| c | d |
| d | NULL |
+------+------+
join_test_r:
+------+------+
| cc | cb |
+------+------+
| a | NULL |
| b | s |
| c | d |
| d | NULL |
+------+------+
当我尝试使用左连接和左侧 <>
过滤器进行查询时 table:
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
的行保留了下来。
当我尝试使用左连接和右侧的 <>
过滤器进行查询时 table:
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
的所有行也被删除。
能解释一下吗?
我的意思是为什么结果集中的空值被 <>
子句过滤?
您需要将 WHERE
子句中的逻辑移动到 ON
子句中:
SELECT *
FROM join_test_l as l
LEFT JOIN join_test_r as r
ON l.cb = r.cb AND r.cc <> 'c';
这里的问题是 WHERE
正在从结果集中过滤掉记录。另一方面,通过将逻辑移动到连接,我们保留了左侧 table join_test_l
中的每条记录。然后,对于 join_test_r
.
中的每一列,未加入任何内容的记录将具有 null
重新 <>
& null
x<>y
当 x
不等于(通常意义上的)y
and x is not null and y is not null
时 true
。当 x
等于(在正常意义上)等于 y
and x is not null and y is not null
时,它是 false
。否则它在技术上是 unknown
,但碰巧被 operators/syntax 当作 null
对待,就像 is
.
大多数 SQL 运算符都是这样的——当每个参数 is not null
和 unknown
(像 null
一样处理)时,它们 return 它们的正常结果除此以外。
SQL 运算符不是同名的普通关系运算符或数学运算符;他们特别对待(值)unknown
& null
。 (说 null
不是一个值是模糊无益的 SQL 文化修辞。)
Re "the "正常意义上的相等",来自MySQL 8.0参考手册
12.3.2 比较函数和运算符:
Comparison operations result in a value of 1
(TRUE
), 0
(FALSE
), or NULL
.
<=>
NULL
-safe equal. This operator performs an equality comparison like the =
operator, but returns 1
rather than NULL
if both operands are NULL
, and 0
rather than NULL if one operand is NULL
. The <=>
operator is equivalent to the standard SQL IS NOT DISTINCT FROM
operator.
注意条件计算结果为 true
的 on
& where
return 行。当约束未评估为 false
.
时,约束得到满足
Re left join
on
& where
了解什么 LEFT/RIGHT JOIN returns:INNER JOIN 行加上不匹配的 left/right table 行由 NULL 扩展。 FULL JOIN returns INNER JOIN rows UNION ALL unmatched left & right table rows extended by NULLs.始终知道您想要什么 INNER JOIN 作为 OUTER JOIN 的一部分。在 OUTER JOIN ON 删除任何由 NULL 扩展的行后,要求可能由 NULL 扩展的列不为 NULL 的 WHERE 或 ON,即仅留下 INNER JOIN 行,即 "turns an OUTER JOIN into an INNER JOIN"。你有那个。
阅读您的 SQL DBMS 文档。
我有 2 个 MySQL table:join_test_l
和 join_test_r
。
join_test_l:
+------+------+
| ca | cb |
+------+------+
| a | s |
| b | s |
| c | d |
| d | NULL |
+------+------+
join_test_r:
+------+------+
| cc | cb |
+------+------+
| a | NULL |
| b | s |
| c | d |
| d | NULL |
+------+------+
当我尝试使用左连接和左侧 <>
过滤器进行查询时 table:
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
的行保留了下来。
当我尝试使用左连接和右侧的 <>
过滤器进行查询时 table:
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
的所有行也被删除。
能解释一下吗?
我的意思是为什么结果集中的空值被 <>
子句过滤?
您需要将 WHERE
子句中的逻辑移动到 ON
子句中:
SELECT *
FROM join_test_l as l
LEFT JOIN join_test_r as r
ON l.cb = r.cb AND r.cc <> 'c';
这里的问题是 WHERE
正在从结果集中过滤掉记录。另一方面,通过将逻辑移动到连接,我们保留了左侧 table join_test_l
中的每条记录。然后,对于 join_test_r
.
null
重新 <>
& null
x<>y
当 x
不等于(通常意义上的)y
and x is not null and y is not null
时 true
。当 x
等于(在正常意义上)等于 y
and x is not null and y is not null
时,它是 false
。否则它在技术上是 unknown
,但碰巧被 operators/syntax 当作 null
对待,就像 is
.
大多数 SQL 运算符都是这样的——当每个参数 is not null
和 unknown
(像 null
一样处理)时,它们 return 它们的正常结果除此以外。
SQL 运算符不是同名的普通关系运算符或数学运算符;他们特别对待(值)unknown
& null
。 (说 null
不是一个值是模糊无益的 SQL 文化修辞。)
Re "the "正常意义上的相等",来自MySQL 8.0参考手册 12.3.2 比较函数和运算符:
Comparison operations result in a value of
1
(TRUE
),0
(FALSE
), orNULL
.
<=>
NULL
-safe equal. This operator performs an equality comparison like the=
operator, but returns1
rather thanNULL
if both operands areNULL
, and0
rather than NULL if one operand isNULL
. The<=>
operator is equivalent to the standard SQLIS NOT DISTINCT FROM
operator.
注意条件计算结果为 true
的 on
& where
return 行。当约束未评估为 false
.
Re left join
on
& where
了解什么 LEFT/RIGHT JOIN returns:INNER JOIN 行加上不匹配的 left/right table 行由 NULL 扩展。 FULL JOIN returns INNER JOIN rows UNION ALL unmatched left & right table rows extended by NULLs.始终知道您想要什么 INNER JOIN 作为 OUTER JOIN 的一部分。在 OUTER JOIN ON 删除任何由 NULL 扩展的行后,要求可能由 NULL 扩展的列不为 NULL 的 WHERE 或 ON,即仅留下 INNER JOIN 行,即 "turns an OUTER JOIN into an INNER JOIN"。你有那个。
阅读您的 SQL DBMS 文档。