这看起来很简单,我很惊讶,因为没有一个更好的词。我有两个表,我们称它们为albums
和artists
CREATE TABLE `albums` (
`album_id` bigint(20) NOT NULL AUTO_INCREMENT,
`artist_id` bigint(20) DEFAULT NULL,
`name` varchar(200) NOT NULL,
PRIMARY KEY (`album_id`)
)
CREATE TABLE `artists` (
`artist_id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(250) NOT NULL,
PRIMARY KEY (`artist_id`)
)
每个表中有几十万个记录。某些专辑行的artist_id
为空,这是意料之中的。
但是,当我执行以下查询来查找没有专辑的艺术家时:
SELECT * FROM artists WHERE artist_id NOT IN (SELECT artist_id FROM albums)
..。查询返回零个结果。我知道这不是真的。所以我尝试了这个:
SELECT * FROM artists WHERE artist_id NOT IN (SELECT artist_id FROM albums WHERE artist_id IS NOT NULL)
..。我得到了几千行数据。我的问题是:为什么第一个查询似乎基于任何数字= NULL的想法进行操作?或者这是NULL对IN()
语句的一种奇怪的影响?我觉得这是我错过的最基本的东西。我通常在我的数据库表中根本不使用NULL。
发布于 2011-07-29 22:51:37
这就是为什么NOT EXISTS
在语义上是正确的
SELECT * FROM artists ar
WHERE NOT EXISTS
(SELECT * FROM albums al WHERE ar.artist_id = al.artist_id)
逻辑:
NOT IN (x, y, NULL)
实际上是NOT (x OR y OR NULL)
实际上是(NOT x) AND (NOT y) AND (NOT NULL)
因此NULL
会使整个NOT IN
无效
发布于 2011-07-29 22:50:48
快速回答- IN
语句是=a OR =b OR ...
的快捷方式。如果你在这个列表中包含nulls,那么我认为这违反了声明。你的第二个选择可能是更好的选择。
或者使用join也可以,而且效率更高。
发布于 2011-07-29 22:55:19
这与SQL NULL的解释方式有关-您必须将它们视为未知值。
假设你有artist_id =1
如果您运行以下命令:
artist_id = NULL
你得到的不是“False”,而是“未知”;
当您运行这样的查询时,只返回计算为'TRUE‘的值。
artist_id IN (NULL, NULL, NULL...) = UNKNOWN
artist_id NOT IN (NULL, NULL, NULL....) = UNKNOWN
https://stackoverflow.com/questions/6874926
复制相似问题