首页 > 解决方案 > 对于 mysql 中的字符串列类型,NOT IN 没有按预期工作

问题描述

我在使用字符串类型列的 NOT IN 和 IN 之间发现了一些奇怪的东西。它适用于 IN 但不适用于 NOT IN。虽然两者都适用于整数类型列(NOT IN 和 IN)

SELECT * FROM `table1` t1 where t1.email not in (select t2.email from `table2` t2)

不会从 t1 返回任何存在于 t2 中的结果,尽管它应该因为有符合条件的记录而

SELECT * FROM `table1` t1 where t1.email in (select t2.email from `table2` t2)

从 t1 返回 t2 中的记录。

标签: mysqlsql

解决方案


这是一个简单的示例来解释这种外观,它也出现在 SQL Server 和 Oracle 等其他 DBMS 中。

假使,假设

select t2.email from `table2` t2

返回

+-------------+
| email       |
+-------------+
| 111@abc.com |
| 222@abc.com |
| NULL        |
+-------------+

执行时

SELECT * FROM `table1` t1 where t1.email not in (select t2.email from `table2` t2)

MySQL 将其翻译成

SELECT * FROM `table1` t1 
where 
t1.email <> '111@abc.com' AND t1.email <> '222@abc.com' AND t1.email <> NULL

where子句总是返回NULL,因为任何值都与NULL返回值进行比较,NULL并且任何布尔值都与返回值进行AND操作。因此,如上所示的整个 SQL 查询总是返回非记录。NULLNULL

相似地,

SELECT * FROM `table1` t1 where t1.email in (select t2.email from `table2` t2)

将被翻译成

SELECT * FROM `table1` t1 
where 
t1.email = '111@abc.com' OR t1.email = '222@abc.com' OR t1.email <> NULL

is的值,如果任何其他比较t1.email <> NULLis NULL,它将被忽略TRUE


推荐阅读