如何理解where col01 in (true)这样的where-in子句?

How to understand such where-in clause as where col01 in (true)?

假设有一个名为 tab01 的 table 并且它在 varchar 类型中有一个名为 col01 的列。和语句如下所示。

# the first statement
SELECT * FROM tab01 WHERE col01 IN (TRUE);
# the second statement
SELECT * FROM tab01 WHERE col01 IN (FALSE);
# the third statement
SELECT * FROM tab01 WHERE col01 IN ('val01');

MySQL 5.7 Reference Manual开始,这三个语句的形式是bit_expr [NOT] IN (expr [, expr] ...)。以我的直觉,只要 expr 被评估为 True,该行就应该被 returned。

为什么第一个语句return什么都没有?在我看来,第一个语句 SELECT * FROM tab01 WHERE col01 IN (TRUE); 应该 return 所有记录,第二个语句 SELECT * FROM tab01 WHERE col01 IN (FALSE); 应该 return 什么都没有。我在这个 MySQL 5.7 Reference Manual 中找不到任何线索。

在 MySQL 中,TRUE 计算为 1。所以第一个查询相当于:

SELECT * FROM tab01 WHERE col01 = 1;

第二个语句的意思是:

SELECT * FROM tab01 WHERE col01 = 0;

如果col01不是数字,MySQL会在比较前进行转换。当比较的数值为 0(通常:'a' = 0 为真)时,这可能会导致令人惊讶的结果。

因为 MySql TRUE 等于 1FALSE 等于 0.
所以第一个语句等同于:

SELECT * FROM tab01 WHERE col01 IN (1);

并且除非列 col01 包含等于 1 的值(或以 1 开头然后包含非数字字符),否则您将不会得到任何 returned .
第二条语句相当于:

SELECT * FROM tab01 WHERE col01 IN (0);

如果列 col01 不包含等于 0 的值,它 也会 也不会 return但是在这种情况下,正如文档Type Conversion in Expression Evaluation中所解释的那样,还有其他因素需要考虑。
假设该列的col01数据类型是varchar,比较:

col01 IN (0)

会将 col01 隐式转换为 INTEGER,除非 col01 的值以数字字符开头,否则此转换的结果将始终为 0所以比较的结果将是 TRUE.
所以你的第二条语句通常会 return 所有行。