我有这张桌子:
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
是否应该包含另一半?我在这里缺少什么?
谢谢
答案 0 :(得分:9)
我认为其余行tbl_1.clean_deep_link
为NULL
。
这些值既不是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_1
中tbl_2
中未包含的每个值,从而检查它们是否为<>
。
您的值不 <> NULL
,因此不 NOT IN
。
另请参阅:Using NOT IN operator with null values
检查SQL Fiddle中的示例。
答案 1 :(得分:2)
MySQL中的NULL
列被视为不同,因此三个NULL
值都被视为不同。
正如其他地方所述,您无法使用传统的比较运算符将NULL
与其他值进行比较,其中包括IN
和NOT 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
);