繁体   English   中英

为什么 MySQL 的 IS TRUE、IS NOT TRUE、IS FALSE、IS NOT FALSE 的行为在 WHERE 和 HAVING 之间是不同的

[英]Why MySQL behavior of IS TRUE, IS NOT TRUE, IS FALSE, IS NOT FALSE is different between WHERE and HAVING

考虑两个表:

表格1

id
1
2
3

表2

id, deleted
2, 0
3, 1

假设我想从 table1 中获取所有在 table2 中没有被标记为“删除”的行,即第 1 行和第 2 行。考虑以下 SQL(在 MySQL 中):

SELECT id
FROM table1
LEFT JOIN table2 USING (id)
WHERE deleted <> 1

这个 SQL 显然只返回 id = 2 的行。

我可以做这样的变态:

SELECT id
FROM table1
LEFT JOIN table2 USING (id)
WHERE COALESCE(deleted, 0) = 0

然后我会得到第 1 行和第 2 行。

但我想要一种更优雅的方式。 MySQL 对布尔值进行了这些很好的检查,IS TRUE、IS NOT TRUE、IS FALSE、IS NOT FALSE 将 NULL 值考虑在内。 所以考虑一下:

SELECT id, deleted, deleted IS NOT TRUE
FROM table1
LEFT JOIN table2 USING (id)

结果:

id, deleted, deleted IS NOT TRUE
1, NULL, TRUE
2, 0, TRUE
3, 1, FALSE

看起来很棒,对吧? 现在,如果我只是将其放入 WHERE 子句中:

SELECT id
FROM table1
LEFT JOIN table2 USING (id)
WHERE deleted IS NOT TRUE

不好了! 我再次得到第 2 行!

但是,如果我将条件放入 HAVING 子句中,它就会开始工作:

SELECT id
FROM table1
LEFT JOIN table2 USING (id)
HAVING deleted IS NOT TRUE

我得到第 1 行和第 2 行。

完全莫名其妙。 似乎是 MySQL 中的一个错误。

正如我怀疑和@BillKarwin 指出的那样,这是 MySQL 中的一个旧的 2012 错误:(

“WHERE var IS NOT TRUE 产量太少”( https://bugs.mysql.com/bug.php?id=67732

我想你只是想要NOT EXISTS

SELECT t1.id
FROM table1 t1 
WHERE NOT EXISTS (SELECT 1
                  FROM table2 t2
                  WHERE t1.id = t2.id AND t2.is_deleted = 1
                 );

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM