MySQL - 为什么NON-NULL列上的LEFT JOIN和NULL条件返回所有行

时间:2017-11-09 13:44:54

标签: mysql join null left-join

MySQL查询是:

     SELECT 
     p1.id,p1.name, p1.category_id, p1.price AS p1_price, p2.price as p2_price 
     FROM
     products p1 
     LEFT JOIN products p2 
     ON p1.category_id=p2.category_id AND  
     p1.price<p2.price AND p2.price IS NULL


products表格显示在以下屏幕截图中:


enter image description here

查询产生的结果如下:

enter image description here

结果实际上只显示了一个包含所有p2_price值的列(即NULL)的表格。

但是AND p2.price IS NULL条件中的条件ON似乎永远不会成为行 表p2中的NULL列中包含price值。那么结果是如何产生的呢?

编辑:此问题从不使用INNER JOIN一词,因此与INNER JOIN的任何问题都不重复。

EDIT2:这个问题是关于MySQL的,因此它不能被称为任何其他语言问题的复制品,例如: SQL。

3 个答案:

答案 0 :(得分:3)

您正在使用LEFT JOIN,这意味着p1将始终保持其值,而当JOIN条件适用时,p2仅为非NULL

也许你想将一些条件移到WHERE子句中:

SELECT 
p1.id,p1.name, p1.category_id, p1.price AS p1_price, p2.price as p2_price 
FROM
products p1 
LEFT JOIN products p2 ON p1.category_id=p2.category_id AND p1.price<p2.price
WHERE p2.price IS NULL

在这些情况下,区分JOIN ON条件和WHERE条件非常重要。 WHERE条件适用于整个结果集。

答案 1 :(得分:1)

LEFT JOIN必须了解的两件事。

第一个:

ON子句仅构建两个表之间的链接。如果左表与此链接不匹配,则有关此表的信息将返回NULL。

如果要剪切这些行,则必须在WHERE子句

中移动条件

第二个:

NULL比较:仅当您使用IS NULL / IS NOT NULL时,才能使用NULL正确处理条件。如果您比较两个字段(例如p1.price和p2.price),如果其中一个为空,则表示您没有TRUEUNKNOWN

答案 2 :(得分:1)

条件on p1.category_id = p2.category_id and p1.price < p2.price and p2.price is null始终为假。因此,生成的连接是产品(p1)的每一行都填充了产品(NULL)列的p2值,例如

  

1,&#39; LG P880 4X HD&#39;,336,3,NULL,NULL,NULL,NULL
  2,&#39;谷歌Nexus 4&#39;,299,2,NULL,NULL,NULL,NULL
  ...
  12,&#39; Abercrombie Lake Arnold Shirt&#39;,60,1,NULL,NULL,NULL,NULL