x = NULL
在雪花中,条件表达式和条件表达式有什么区别x IS NULL
?x IS NULL
当我想查找某些列为空白的行时,从经验上看,这似乎是我想要的。我问是因为x = NULL
被视为有效语法,我很好奇这个表达式是否有不同的应用程序。
3 回答
x = NULL 和 x IS NULL 有什么区别
在 Snowflake 中,就像在其他 RDBMS 中一样,Nothing 等于NULL
(甚至NULL
它本身),因此条件x = NULL
(这是有效的 SQL 语法)将始终评估为 false(实际上,它NULL
在大多数 RDBMS 中评估为,这是不正确的)。请注意,这对于非相等比较也是正确的:这NULL <> NULL
也是错误的。
检查变量是否为 is 的典型方法NULL
是使用x IS NULL
构造,该构造评估为 true if x
is NULL
。你也可以用x IS NOT NULL
。此语法是为 保留的NULL
,因此类似于x IS y
语法错误。
这是一个小演示:
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
像大多数 SQL 语言一样,比较NULL = NULL
不会返回TRUE
. 在 SnowFlake 中,它返回NULL
,与值的 ANY 比较一样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)
这种特殊情况在 Snowflake 的文档中得到了很好的描述:
比较两个表达式是否相等。该函数是 NULL 安全的,这意味着它将 NULL 视为比较相等性的已知值。请注意,这与 EQUAL 比较运算符 (=) 不同,后者将 NULL 视为未知值。
+------+------+--------------------------------+------------------------------------------+----------------------------+--------------------------------------+
| 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 |
+------+------+--------------------------------+------------------------------------------+----------------------------+--------------------------------------+