Подтвердить что ты не робот

IN с NULL или NULL

Postgres - это база данных

Можно ли использовать значение NULL для предложения IN? Пример:

SELECT *
FROM tbl_name
WHERE id_field IN ('value1', 'value2', 'value3', NULL)

Я хочу ограничить эти четыре значения.

Я пробовал вышеуказанный оператор, и он не работает, но он выполняет, но не добавляет записи с NULL id_fields.

Я также попытался добавить условие ИЛИ, но это просто заставляет запрос запускать и запускать без конца.

SELECT *
FROM tbl_name
WHERE other_condition = bar
AND another_condition = foo
AND id_field IN ('value1', 'value2', 'value3')
OR id_field IS NULL

Любые предложения?

4b9b3361

Ответ 1

Оператор in будет анализироваться идентично field=val1 or field=val2 or field=val3. Ввод нулевого значения будет сжиматься до field=null, который не будет работать.

(Comment Marc B)

Я сделал бы это для clairity

SELECT *
FROM tbl_name
WHERE 
(id_field IN ('value1', 'value2', 'value3') OR id_field IS NULL)

Ответ 2

Ваш запрос завершился неудачно из-за приоритет оператора. AND привязывается до OR!
Вам нужна пара круглых скобок, что не является вопросом "ясности", а чистой логической необходимостью.

SELECT *
FROM   tbl_name
WHERE  other_condition = bar
AND    another_condition = foo
AND   (id_field IN ('value1', 'value2', 'value3') OR id_field IS NULL)

Добавленные круглые скобки препятствуют привязке AND до OR. Если не было других WHERE условий (нет AND), вам не нужны скобки. Принятый ответ немного вводит в заблуждение в этом отношении.

Ответ 3

Вопрос, на который ответил Даниил, совершенно прав. Я хотел оставить записку о NULLS. Мы должны быть осторожны в использовании оператора NOT IN, если столбец содержит значения NULL. Вы не получите никакого вывода, если ваш столбец содержит значения NULL, и вы используете оператор NOT IN. Вот как это объясняется здесь http://www.oraclebin.com/2013/01/beware-of-nulls.html, очень хорошая статья, с которой я столкнулся и подумал поделиться ею.

Ответ 4

SELECT *
FROM tbl_name
WHERE coalesce(id_field,'unik_null_value') 
IN ('value1', 'value2', 'value3', 'unik_null_value')

Чтобы исключить null из проверки. Учитывая значение null в id_field, функция coalesce вместо null возвращает unix_null_value и добавляет 'unik_null_value к IN-list, запрос будет возвращать сообщения, где id_field имеет значение 1-3 или null.

Ответ 5

Примечание:. Поскольку кто-то утверждал, что внешняя ссылка мертва в ответе Sushant Butta​​strong > , я разместил здесь контент в виде отдельного ответа.

Остерегайтесь NULLS.

Сегодня я столкнулся с очень странным поведением запроса при использовании операторов IN и NOT IN. На самом деле я хотел сравнить две таблицы и выяснить, существует ли значение из table b в table a или нет, и выяснить его поведение, если столбец содержит значения null. Поэтому я просто создал среду для проверки этого поведения.

Мы создадим таблицу table_a.

SQL> create table table_a ( a number);
Table created.

Мы создадим таблицу table_b.

SQL> create table table_b ( b number);
Table created.

Вставьте несколько значений в table_a.

SQL> insert into table_a values (1);
1 row created.

SQL> insert into table_a values (2);
1 row created.

SQL> insert into table_a values (3);
1 row created.

Вставьте некоторые значения в table_b.

SQL> insert into table_b values(4);
1 row created.

SQL> insert into table_b values(3);
1 row created.

Теперь мы выполним запрос для проверки существования значения в table_a, проверив его значение из table_b с помощью оператора IN.

SQL> select * from table_a where a in (select * from table_b);
         A
----------
         3

Выполните следующий запрос, чтобы проверить отсутствие.

SQL> select * from table_a where a not in (select * from table_b);
         A
----------
         1
         2

Выход был таким, как ожидалось. Теперь мы вставим значение null в таблицу table_b и посмотрим, как ведут себя эти два запроса.

SQL> insert into table_b values(null);
1 row created.

SQL> select * from table_a where a in (select * from table_b);
         A
----------
         3

SQL> select * from table_a where a not in (select * from table_b);

no rows selected

Первый запрос вел себя так, как ожидалось, но что случилось со вторым запросом? Почему мы не получили какой-либо результат, что должно было произойти? Есть ли разница в запросе? Нет.

Изменение приведено в таблице table_b. Мы ввели значение null в таблице. Но как это происходит? Пусть разделить два запроса на "AND" и "OR".

Первый запрос:

Первый запрос будет обрабатываться внутри что-то вроде этого. Таким образом, null не будет создавать проблему здесь, так как мои первые два операнда будут либо оцениваться как true или false. Но мой третий операнд a = null не будет оценивать до true и false. Он будет оцениваться только null.

select * from table_a whara a = 3 or a = 4 or a = null;

a = 3  is either true or false
a = 4  is either true or false
a = null is null

Второй запрос:

Второй запрос будет обработан, как показано ниже. Поскольку мы используем оператор "AND", и ничего, кроме true в любом из операндов, не даст мне никакого вывода.

select * from table_a whara a <> 3 and a <> 4 and a <> null;

a <> 3 is either true or false
a <> 4 is either true or false
a <> null is null

Итак, как мы справляемся с этим? Мы будем выбирать все значения not null из таблицы table_b при использовании оператора NOT IN.

SQL> select * from table_a where a not in (select * from table_b where b is not null);

         A
----------
         1
         2

Поэтому всегда будьте осторожны с значениями null в столбце при использовании оператора NOT IN.

Остерегайтесь NULL!!