为什么 "AND NOT field = 'value'" 过滤掉空值?
Why is "AND NOT field = 'value'" filtering out nulls?
我的查询基本上像
WITH DATA AS(
SELECT fields
FROM table
WHERE [many conditions]
AND NOT field1 = 'string'
)
SELECT foo,
bar,
CASE
WHEN field1 IS NULL THEN 'other_string'
[other cases]
END
FROM data
还有很多其他事情正在发生,但这是不起作用的核心部分。 应该给我很多结果。但相反,该特定案例的结果为零;如果我删除查询的其余部分并且 运行 基本上就是这个,它只是一个空的 table.
AND NOT field1 = 'string'
似乎过滤掉了 field1 为 'string' 的所有行,但也过滤掉了 field1 为空的所有行。如果 field1 为 null,那么 field1 = 'string'
应该评估为 false(因为 null 不等于任何东西)因此 NOT field1 = 'string'
应该评估为 true 并且这些行应该在查询中 - 对吧?
实际上不确定我正在使用的 Redash 前端 运行 背后的 sql 实现是什么,但我可以找出它是否相关。
如果将 NULL
与 SQL 中的另一个值进行比较,结果将为 NULL
。但是,当您使用 IS NULL
或 IS NOT NULL
进行显式比较时,将相应地考虑 NULL 值。
所以你的情况应该是
(NOT (field1 = 'string') OR field1 IS NULL)
或者可能更具可读性(<>
表示不等于):
(field1 <> 'string' OR field1 IS NULL)
Here 您可以找到有关 SQL NULL 值的一些详细信息。
It is not possible to test for NULL values with comparison operators, such as =, <, or <>.
We will have to use the IS NULL and IS NOT NULL operators instead.
几乎所有与NULL
returns NULL
的比较。两个突出的例外是 IS NULL
和 IS NOT NULL
,其中 return 要么是“真”要么是“假”。
NULL
具有非常简单的语义:
NOT NULL
--> NULL
TRUE AND NULL
--> NULL
FALSE AND NULL
--> FALSE
TRUE OR NULL
--> TRUE
FALSE OR NULL
--> NULL
如果您认为 NULL
代表一个 *unknown" 值而不是 missing 值,那么语义更容易理解。
A WHERE
子句只传递计算结果为“真”的行。因此,“false”和 NULL
都被删除了。请注意,这与 CASE
表达式相同。但是,CHECK
表达式将 NULL
视为“真”。嗯,没有人指责 SQL 内部一致性。
你的表达是:
WHERE [many conditions] AND NOT field1 = 'string'
当 field1
为 NULL
时:
WHERE [many conditions] AND NOT (NULL = 'string')
WHERE [many conditions] AND NOT (NULL)
WHERE [many conditions] AND NULL
WHERE NULL
非常简单的逻辑。
注意:标准 SQL 有一个 NULL
安全比较器,即:
WHERE [many conditions] AND field1 IS DISTINCT FROM 'string'
一些数据库为此目的使用 <=>
:
WHERE [many conditions] AND NOT field1 <=>'string'
而在其他情况下,您需要更加明确:
WHERE [many conditions] AND (field1 <> 'string' OR field1 IS NULL)
我的查询基本上像
WITH DATA AS(
SELECT fields
FROM table
WHERE [many conditions]
AND NOT field1 = 'string'
)
SELECT foo,
bar,
CASE
WHEN field1 IS NULL THEN 'other_string'
[other cases]
END
FROM data
还有很多其他事情正在发生,但这是不起作用的核心部分。 应该给我很多结果。但相反,该特定案例的结果为零;如果我删除查询的其余部分并且 运行 基本上就是这个,它只是一个空的 table.
AND NOT field1 = 'string'
似乎过滤掉了 field1 为 'string' 的所有行,但也过滤掉了 field1 为空的所有行。如果 field1 为 null,那么 field1 = 'string'
应该评估为 false(因为 null 不等于任何东西)因此 NOT field1 = 'string'
应该评估为 true 并且这些行应该在查询中 - 对吧?
实际上不确定我正在使用的 Redash 前端 运行 背后的 sql 实现是什么,但我可以找出它是否相关。
如果将 NULL
与 SQL 中的另一个值进行比较,结果将为 NULL
。但是,当您使用 IS NULL
或 IS NOT NULL
进行显式比较时,将相应地考虑 NULL 值。
所以你的情况应该是
(NOT (field1 = 'string') OR field1 IS NULL)
或者可能更具可读性(<>
表示不等于):
(field1 <> 'string' OR field1 IS NULL)
Here 您可以找到有关 SQL NULL 值的一些详细信息。
It is not possible to test for NULL values with comparison operators, such as =, <, or <>. We will have to use the IS NULL and IS NOT NULL operators instead.
几乎所有与NULL
returns NULL
的比较。两个突出的例外是 IS NULL
和 IS NOT NULL
,其中 return 要么是“真”要么是“假”。
NULL
具有非常简单的语义:
NOT NULL
-->NULL
TRUE AND NULL
-->NULL
FALSE AND NULL
-->FALSE
TRUE OR NULL
-->TRUE
FALSE OR NULL
-->NULL
如果您认为 NULL
代表一个 *unknown" 值而不是 missing 值,那么语义更容易理解。
A WHERE
子句只传递计算结果为“真”的行。因此,“false”和 NULL
都被删除了。请注意,这与 CASE
表达式相同。但是,CHECK
表达式将 NULL
视为“真”。嗯,没有人指责 SQL 内部一致性。
你的表达是:
WHERE [many conditions] AND NOT field1 = 'string'
当 field1
为 NULL
时:
WHERE [many conditions] AND NOT (NULL = 'string')
WHERE [many conditions] AND NOT (NULL)
WHERE [many conditions] AND NULL
WHERE NULL
非常简单的逻辑。
注意:标准 SQL 有一个 NULL
安全比较器,即:
WHERE [many conditions] AND field1 IS DISTINCT FROM 'string'
一些数据库为此目的使用 <=>
:
WHERE [many conditions] AND NOT field1 <=>'string'
而在其他情况下,您需要更加明确:
WHERE [many conditions] AND (field1 <> 'string' OR field1 IS NULL)