where条件可能为null_关于MySQLLEFTJOIN你可能需要知道
的三点
即使你认为⾃⼰已对 MySQL 的 LEFT JOIN 理解深刻,但我敢打赌,这篇⽂章肯定能让你学会点东西!
ON ⼦句与 WHERE ⼦句的不同
⼀种更好地理解带有 WHERE ... IS NULL ⼦句的复杂匹配条件的简单⽅法
Matching-Conditions 与 Where-conditions 的不同
关于 “A LEFT JOIN B ON 条件表达式” 的⼀点提醒
ON这条件(“A LEFT JOIN B ON 条件表达式”中的ON)⽤来决定如何从 B 表中检索数据⾏。
如果 B 表中没有任何⼀⾏数据匹配 ON 的条件,将会额外⽣成⼀⾏所有列为 NULL 的数据
在匹配阶段 WHERE ⼦句的条件都不会被使⽤。仅在匹配阶段完成以后,WHERE ⼦句条件才会被使⽤。它将从匹配阶段产⽣的数据中检
索过滤。
让我们看⼀个 LFET JOIN ⽰例:
mysql> CREATE TABLE `product` (  `id` int(10) unsigned NOT NULL auto_increment,  `amount` int(10) unsigned default NULL,  PRIMARY KEY  (`id`)) EN ON ⼦句和 WHERE ⼦句有什么不同?
⼀个问题:下⾯两个查询的结果集有什么不同么?
1. SELECT * FROM product LEFT JOIN product_details        ON (product.id = product_details.id)        AND  product_details.id=2;
2. SELECT * FROM pro ⽤例⼦来理解最好不过了:
mysql> SELECT * FROM product LEFT JOIN product_details      ON (product.id = product_details.id)      AND product_details.id=2;+----+--------+------+----第⼀条查询使⽤ ON 条件决定了从 LEFT JOIN的 product_details表中检索符合的所有数据⾏。
第⼆条查询做了简单的LEFT JOIN,然后使⽤ WHERE ⼦句从 LEFT JOIN的数据中过滤掉不符合条件的数据⾏。
多表left join再来看⼀些⽰例:
mysql>mysql> SELECT * FROM product LEFT JOIN product_details      ON product.id = product_details.id      AND product.amount=100;+----+--------+---
所有来⾃product表的数据⾏都被检索到了,但没有在product_details表中匹配到记录(product.id = product_details.id AND
product.amount=100 条件并没有匹配到任何数据)
mysql> SELECT * FROM product LEFT JOIN product_details      ON (product.id = product_details.id)      AND product.amount=200;+----+--------+------+---同样,所有来⾃product表的数据⾏都被检索到了,有⼀条数据匹配到了。
使⽤ WHERE ... IS NULL ⼦句的 LEFT JOIN
当你使⽤ WHERE ... IS NULL ⼦句时会发⽣什么呢?
如前所述,WHERE 条件查询发⽣在 匹配阶段之后,这意味着 WHERE ... IS NULL ⼦句将从匹配阶段后的数据中过滤掉不满⾜匹配条件的数据⾏。
纸⾯上看起来很清楚,但是当你在 ON ⼦句中使⽤多个条件时就会感到困惑了。
我总结了⼀种简单的⽅式来理解上述情况:
将 IS NULL 作为否定匹配条件
使⽤ !(A and B) == !A OR !B 逻辑判断
看看下⾯的⽰例:
mysql> SELECT a.* FROM product a LEFT JOIN product_details b      ON a.id=b.id AND b.weight!=44 ist=0      WHERE b.id IS NULL;+----+------让我们检查⼀下 ON 匹配⼦句:
(a.id=b.id) AND (b.weight!=44) AND (b.exist=0)
我们可以把 IS NULL ⼦句 看作是否定匹配条件。
这意味着我们将检索到以下⾏:
!( exist(b.id that equals to a.id) AND b.weight !=44 ist=0 )!exist(b.id that equals to a.id) || !(b.weight !=44) || !(b.exist=0)!exist(b.id that equals to a.i
就像在C语⾔中的逻辑 AND 和 逻辑 OR表达式⼀样,其操作数是从左到右求值的。如果第⼀个参数⾜够判断操作结果,那么第⼆个参数便不会被计算求值(短路效果)
看看别的⽰例:
mysql> SELECT a.* FROM product a LEFT JOIN product_details b      ON a.id=b.id AND b.weight!=44 ist=1      WHERE b.id IS NULL;+----+------Matching-Conditions 与 Where-conditions 之战
如果你把基本的查询条件放在 ON ⼦句中,把剩下的否定条件放在 WHERE ⼦句中,那么你会获得相同的结果。
例如,你可以不这样写:
SELECT a.* FROM product a LEFT JOIN product_details bON a.id=b.id AND b.weight!=44 ist=0WHERE b.id IS NULL;
你可以这样写:
SELECT a.* FROM product a LEFT JOIN product_details bON a.id=b.idWHERE b.id is null OR b.weight=44 ist=1;
mysql> SELECT a.* FROM product a LEFT JOIN product_details b      ON a.id=b.id      WHERE b.id is null OR b.weight=44 ist=1;+----+--------+| id 你可以不这样写:
SELECT a.* FROM product a LEFT JOIN product_details bON a.id=b.id AND b.weight!=44 ist!=0WHERE b.id IS NULL;
可以这样写:
SELECT a.* FROM product a LEFT JOIN product_details bON a.id=b.idWHERE b.id is null OR b.weight=44 ist=0;
mysql> SELECT a.* FROM product a LEFT JOIN product_details b      ON a.id=b.id      WHERE b.id is null OR b.weight=44 ist=0;+----+--------+| id
这些查询真的效果⼀样?
如果你只需要第⼀个表中的数据的话,这些查询会返回相同的结果集。有⼀种情况就是,如果你从 LEFT JOIN的表中检索数据时,查询的
结果就不同了。
如前所述,WHERE ⼦句是在匹配阶段之后⽤来过滤的。
例如:
mysql> SELECT * FROM product a LEFT JOIN product_details b      ON a.id=b.id AND b.weight!=44 ist=1      WHERE b.id is null;+----+--------+--总附注:
如果你使⽤ LEFT JOIN 来寻在⼀些表中不存在的记录,你需要做下⾯的测试:WHERE 部分的 col_name IS NULL(其中 col_name 列被定义为 NOT NULL),MYSQL 在查询到⼀条匹配 LEFT JOIN 条件后将停⽌搜索更多⾏(在⼀个特定的组合键下)

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。