NOT IN的奇怪行为

时间:2012-05-16 07:36:36

标签: mysql sql

我有这张桌子:

select count(distinct clean_deep_link) from tbl_1;
+---------------------------------+
| count(distinct clean_deep_link) |
+---------------------------------+
|                          121211 |
+---------------------------------+

我有这个问题:

select count(1) from tbl_1 where clean_deep_link IN
  (select clean_deep_link from tbl_2);

+----------+
| count(1) |
+----------+
|    66360 |
+----------+

但是当我将查询更改为not in时,它会返回一个空集:

select count(1) from tbl_1
where clean_deep_link not in (select clean_deep_link from tbl_2);
+----------+
| count(1) |
+----------+
|        0 |
+----------+

这怎么可能?如果子查询包含大约一半的记录,那么子查询的not是否应该包含另一半?我在这里缺少什么?

谢谢

3 个答案:

答案 0 :(得分:9)

我认为其余行tbl_1.clean_deep_linkNULL

这些值既不是IN也不是NOT IN您的子查询。


另一个原因可能是NULL中有tbl_2.clean_deep_link

请尝试以下方法:

select count(1) from tbl_1
where clean_deep_link not in (select clean_deep_link
                              from tbl_2 WHERE clean_deep_link IS NOT NULL);

NULL的问题在于它既不是=,也不是<>任何其他值(包括NULL)。

检查NOT IN时,MySQL需要检查tbl_1tbl_2中未包含的每个值,从而检查它们是否为<>

您的值 <> NULL,因此 NOT IN

另请参阅:Using NOT IN operator with null values


检查SQL Fiddle中的示例。

答案 1 :(得分:2)

MySQL中的NULL列被视为不同,因此三个NULL值都被视为不同。

正如其他地方所述,您无法使用传统的比较运算符将NULL与其他值进行比较,其中包括INNOT IN

以下运算符可以处理NULL

x <=> y - returns 1 if x == y (even if both are NULL)
x IS NULL - returns 1 if x is null
x IS NOT NULL - returns 0 if x is null

答案 2 :(得分:0)

SELECT COUNT(*) - COUNT(1) 
FROM tbl_1 
WHERE clean_deep_link IN (
    SELECT clean_deep_link 
    FROM tbl_2
);