x = null 与 x IS NULL 之间的区别
Difference between x = null vs. x IS NULL
在 Snowflake 中,条件表达式中的 x = NULL
和 x IS NULL
有什么区别?根据经验,当我想查找某些列为空白的行时, x IS NULL
就是我想要的。我问是因为 x = NULL
被视为有效语法,我很好奇这个表达式是否有不同的应用程序。
与大多数 SQL 语言一样,比较 NULL = NULL
不会 return TRUE
。在 SnowFlake 中,它 returns NULL
,与 NULL
值的任何比较也是如此。其原因与 SQL 的错综复杂的历史有关,并且一直在争论这是否是一个好功能。无论如何,这就是我们所拥有的。
因此,当您比较两个可能为 NULL 的值时,这里有一些您通常可以使用的不同解决方案。
-- NVL will return the second value if the first value is NULL
-- So if both of your values are NULL, then an NVL around each of them will
-- return a value so that they are both equal.
-- This only works if you know that your values will never be equal to -1 for example
SELECT ...
WHERE NVL(x, -1) = NVL(y, -1)
-- A little messier, especially among more complicated filters,
-- but guaranteed to work regardless of values
SELECT ...
WHERE x = y OR (x is null and y is null)
-- My new favorite which works in SnowFlake (thanks to @waldente)
SELECT x IS NOT DISTINCT FROM y;
-- For most SQL languages, this is a neat way to take advantage of how
-- INTERSECT compares values which does treat NULLs as equal
SELECT ...
WHERE exists (select x intersect select y)
what is the difference between x = NULL and x IS NULL
在 Snowflake 中就像在其他 RDBMS 中一样,Nothing 等于 NULL
(甚至 NULL
本身),因此条件 x = NULL
(这是有效的 SQL 语法) 将始终评估为 false(好吧,实际上,在大多数 RDBMS 中它评估为 NULL
,这是不正确的)。请注意,对于非相等比较也是如此:即 NULL <> NULL
也是错误的。
检查变量是否为 NULL
的典型方法是使用 x IS NULL
结构,如果 x
为 NULL
,则其计算结果为真。您也可以使用 x IS NOT NULL
。此语法是为 NULL
保留的,因此 x IS y
是语法错误。
这里是a small demo:
select
case when 1 = null then 1 else 0 end 1_equal_null,
case when 1 <> null then 1 else 0 end 1_not_equal_null,
case when null is null then 1 else 0 end null_is_null,
case when 1 is not null then 1 else 0 end 1_is_not_null
1_equal_null | 1_not_equal_null | null_is_null | 1_is_not_null
-----------: | ---------------: | -----------: | ------------:
0 | 0 | 1 | 1
这种特殊情况在 Snowflake 的文档中有详细描述:
Compares whether two expressions are equal. The function is NULL-safe, meaning it treats NULLs as known values for comparing equality. Note that this is different from the EQUAL comparison operator (=), which treats NULLs as unknown values.
+------+------+--------------------------------+------------------------------------------+----------------------------+--------------------------------------+
| X1_I | X2_I | X1.I IS NOT DISTINCT FROM X2.I | SELECT IF X1.I IS NOT DISTINCT FROM X2.I | X1.I IS DISTINCT FROM X2.I | SELECT IF X1.I IS DISTINCT FROM X2.I |
|------+------+--------------------------------+------------------------------------------+----------------------------+--------------------------------------|
| 1 | 1 | True | Selected | False | Not |
| 1 | 2 | False | Not | True | Selected |
| 1 | NULL | False | Not | True | Selected |
| 2 | 1 | False | Not | True | Selected |
| 2 | 2 | True | Selected | False | Not |
| 2 | NULL | False | Not | True | Selected |
| NULL | 1 | False | Not | True | Selected |
| NULL | 2 | False | Not | True | Selected |
| NULL | NULL | True | Selected | False | Not |
+------+------+--------------------------------+------------------------------------------+----------------------------+--------------------------------------+
在 Snowflake 中,条件表达式中的 x = NULL
和 x IS NULL
有什么区别?根据经验,当我想查找某些列为空白的行时, x IS NULL
就是我想要的。我问是因为 x = NULL
被视为有效语法,我很好奇这个表达式是否有不同的应用程序。
与大多数 SQL 语言一样,比较 NULL = NULL
不会 return TRUE
。在 SnowFlake 中,它 returns NULL
,与 NULL
值的任何比较也是如此。其原因与 SQL 的错综复杂的历史有关,并且一直在争论这是否是一个好功能。无论如何,这就是我们所拥有的。
因此,当您比较两个可能为 NULL 的值时,这里有一些您通常可以使用的不同解决方案。
-- NVL will return the second value if the first value is NULL
-- So if both of your values are NULL, then an NVL around each of them will
-- return a value so that they are both equal.
-- This only works if you know that your values will never be equal to -1 for example
SELECT ...
WHERE NVL(x, -1) = NVL(y, -1)
-- A little messier, especially among more complicated filters,
-- but guaranteed to work regardless of values
SELECT ...
WHERE x = y OR (x is null and y is null)
-- My new favorite which works in SnowFlake (thanks to @waldente)
SELECT x IS NOT DISTINCT FROM y;
-- For most SQL languages, this is a neat way to take advantage of how
-- INTERSECT compares values which does treat NULLs as equal
SELECT ...
WHERE exists (select x intersect select y)
what is the difference between x = NULL and x IS NULL
在 Snowflake 中就像在其他 RDBMS 中一样,Nothing 等于 NULL
(甚至 NULL
本身),因此条件 x = NULL
(这是有效的 SQL 语法) 将始终评估为 false(好吧,实际上,在大多数 RDBMS 中它评估为 NULL
,这是不正确的)。请注意,对于非相等比较也是如此:即 NULL <> NULL
也是错误的。
检查变量是否为 NULL
的典型方法是使用 x IS NULL
结构,如果 x
为 NULL
,则其计算结果为真。您也可以使用 x IS NOT NULL
。此语法是为 NULL
保留的,因此 x IS y
是语法错误。
这里是a small demo:
select
case when 1 = null then 1 else 0 end 1_equal_null,
case when 1 <> null then 1 else 0 end 1_not_equal_null,
case when null is null then 1 else 0 end null_is_null,
case when 1 is not null then 1 else 0 end 1_is_not_null
1_equal_null | 1_not_equal_null | null_is_null | 1_is_not_null -----------: | ---------------: | -----------: | ------------: 0 | 0 | 1 | 1
这种特殊情况在 Snowflake 的文档中有详细描述:
Compares whether two expressions are equal. The function is NULL-safe, meaning it treats NULLs as known values for comparing equality. Note that this is different from the EQUAL comparison operator (=), which treats NULLs as unknown values.
+------+------+--------------------------------+------------------------------------------+----------------------------+--------------------------------------+
| X1_I | X2_I | X1.I IS NOT DISTINCT FROM X2.I | SELECT IF X1.I IS NOT DISTINCT FROM X2.I | X1.I IS DISTINCT FROM X2.I | SELECT IF X1.I IS DISTINCT FROM X2.I |
|------+------+--------------------------------+------------------------------------------+----------------------------+--------------------------------------|
| 1 | 1 | True | Selected | False | Not |
| 1 | 2 | False | Not | True | Selected |
| 1 | NULL | False | Not | True | Selected |
| 2 | 1 | False | Not | True | Selected |
| 2 | 2 | True | Selected | False | Not |
| 2 | NULL | False | Not | True | Selected |
| NULL | 1 | False | Not | True | Selected |
| NULL | 2 | False | Not | True | Selected |
| NULL | NULL | True | Selected | False | Not |
+------+------+--------------------------------+------------------------------------------+----------------------------+--------------------------------------+