为什么带有!= 0的SQL查询不包含NULL值?

dgi*_*gig 6 mysql comparison null sqlfiddle

这是两个测试表的sqlfiddle:http://sqlfiddle.com/#!9/33361/3

tl; dr:为什么SQL查询!= 0不包含NULL值?

我是LEFT JOIN这两张桌子.我希望看到包含NULLin tableB.field11in的行tableB.field1,但是排除所有包含0in的行tableB.field1.

我认为这个查询(例6)应该给我这个结果,但它不会得到空记录.

SELECT * FROM tableA a
LEFT JOIN tableB b ON a.id = b.join_id
WHERE
b.field1 != 0;
Run Code Online (Sandbox Code Playgroud)

我必须使用这个更长的查询(例4):

SELECT * FROM tableA a
LEFT JOIN tableB b ON a.id = b.join_id
WHERE
b.field1 != 0 OR b.field1 IS NULL;
Run Code Online (Sandbox Code Playgroud)

只是好奇多了 - MySQL怎么不考虑NULL!= 0?

当我将条件移动到ON子句时,我得到一个意外的行:

mysql> SELECT * FROM tableA a
    -> LEFT JOIN tableB b ON a.id = b.join_id AND b.field1 != 0;
+------+--------+--------+---------+--------+--------+
| id   | field1 | field2 | join_id | field1 | field2 |
+------+--------+--------+---------+--------+--------+
|    1 | testA1 | testA1 |       1 | 1      | testB1 |
|    2 | testA2 | testA2 |    NULL | NULL   | NULL   |
|    3 | testA3 | testA3 |    NULL | NULL   | NULL   |
+------+--------+--------+---------+--------+--------+
3 rows in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

Sev*_*vle 6

为什么带有!= 0的SQL查询不包含NULL值?

简短答案:因为SELECT 0 != NULL回报(NULL)

更长的答案:根据MySQL的文档

您不能使用算术比较运算符(例如=,<或<>)测试NULL。

如果要在Select子句中包含NULL,则必须借助“ IS NULL”或“ IFNULL”将其转换为算术表示形式。

您的SQL查询可以重写为:

SELECT * 
FROM tableA a
LEFT JOIN tableB b ON a.id = b.join_id
WHERE
    IFNULL(b.field1, -1) != 0;
Run Code Online (Sandbox Code Playgroud)

  • 或者只使用MySQL的NULL安全相等比较运算符[`&lt;=&gt;`](https://dev.mysql.com/doc/en/comparison-operators.html#operator_equal-to)-例如,“ WHERE NOT” b.field1 &lt;=&gt; 0`。 (4认同)

Nae*_*Nae 6

来自 Eggyal 的评论“或者只使用 MySQL 的 NULL 安全相等比较运算符,<=> \xe2\x80\x94e.g. WHERE NOT b.field1 <=> 0”。

\n\n
SELECT * FROM tableA a\nLEFT JOIN tableB b ON a.id = b.join_id\nWHERE NOT b.field1 <=> 0\n;\n
Run Code Online (Sandbox Code Playgroud)\n