Разница между х = ноль и х ноль - PullRequest
2 голосов
/ 09 января 2020

В Snowflake, в чем разница между x = NULL и x IS NULL в выражении условия? Эмпирически кажется, что x IS NULL - это то, что я хочу, когда хочу найти строки, где какой-то столбец пуст. Я спрашиваю, потому что x = NULL считается допустимым синтаксисом, и мне любопытно, есть ли другое приложение для этого выражения.

Ответы [ 3 ]

5 голосов
/ 09 января 2020

в чем разница между x = NULL и x IS NULL

В Snowflake, как и в других СУБД, ничто не равно NULL (даже NULL), таким образом, условие x = NULL (допустимый синтаксис SQL) всегда будет оцениваться как ложное (ну, на самом деле, оно оценивается как NULL в большинстве СУБД, что не соответствует действительности). Обратите внимание, что это также верно для сравнений на неравенство: то есть NULL <> NULL также ложно.

Типичный способ проверить, является ли переменная NULL, состоит в использовании конструкции x IS NULL, которая оценивает как истина, если x равно 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
1 голос
/ 09 января 2020

Как и большинство языков SQL, сравнение NULL = NULL не возвращает TRUE. В SnowFlake он возвращает 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)
0 голосов
/ 02 мая 2020

Этот конкретный случай хорошо описан в документации Snowflake:

EQUAL_NULL

НЕ [ОТЛИЧНО] ОТ

Сравнивает, равны ли два выражения. Функция 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                                  |
+------+------+--------------------------------+------------------------------------------+----------------------------+--------------------------------------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...