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

Why does a SQL query with != 0 not include NULL values?

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

tl;dr:为什么带有 != 0 的 SQL 查询不包括 NULL 值?

我正在加入这两个表。我想查看在 tableB.field1 中具有 NULL 或在 tableB.field1 中具有 1 的行,但排除在 [=17] 中具有 0 的所有行=].

我认为这个查询(示例 6)应该给我这个结果,但它没有得到空记录。

SELECT * FROM tableA a
LEFT JOIN tableB b ON a.id = b.join_id
WHERE
b.field1 != 0;

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

SELECT * FROM tableA a
LEFT JOIN tableB b ON a.id = b.join_id
WHERE
b.field1 != 0 OR b.field1 IS NULL;

只是好奇 - MySQL 怎么不认为 N​​ULL 是 != 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)

使用外部联接时,SQL 引擎使用空值表示组合集中缺少数据。对空值的相等性检查总是 return false.

考虑:当 null = null then 1 else 0 end 这将始终产生 0 的情况!

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

在您的查询中,where 子句在引擎生成连接数据集后应用。
假设 A 的 ID 为 1,2 而 B 只有 1.

您的左连接结果集将没有 where 子句:

  A.ID B.ID
    1  1
    2  NULL

您的 where 子句已应用 b.field !=0

你会得到

  A.ID B.ID
    1  1

Null 相等性检查的计算结果始终为 FALSE,因此排除第 2 行并保留第 1 行。

如果将筛选器移动到加入条件,则在 table 加入之前应用限制。

SELECT * FROM tableA a
LEFT JOIN tableB b 
   ON a.id = b.join_id
  and b.field1 != 0;

  A.ID B.ID
    1  1
    2  NULL

并且由于 B 中没有第 2 行的记录,所以您得到这两行。

MySQL怎么不把NULL当成!=0呢?

Null 是一个特例。与 null 的相等比较总是会产生 false。

is nullis not null 是可用于检查值是否为空的两种方法。

您也可以使用 where coalesce(b.field1,1) != 0 来确保第二条记录被 return 编辑。尽管您最好将左连接中第 2 个 table 上的任何过滤器简单地移动到连接条件。

Why does a SQL query with != 0 not include NULL values?

简答:因为SELECT 0 != NULLreturns(NULL)

更长的答案:根据 MySQL's documentation

You cannot use arithmetic comparison operators such as =, <, or <> to test for 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;
w=14=shsh=12=sh——例如w=11=sh."w=15=shsh=13=sh w=10=sh