In Clause with NULL or IS NULL

o Postgres é a base de dados

Posso usar um valor nulo para uma cláusula IN? exemplo:

SELECT *
FROM tbl_name
WHERE id_field IN ('value1', 'value2', 'value3', NULL)
Quero limitar - me a estes quatro valores.

eu tentei a declaração acima e não funciona, bem ele executa mas não adiciona os registros com id_fields nulos.

eu também tentei adicionar uma condição ou, mas isso apenas fazer a consulta executar e executar sem fim à vista.

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

Author: Phill Pafford, 2011-06-15

6 answers

Uma declaração in será analisada de forma idêntica a field=val1 or field=val2 or field=val3. Colocar um null lá dentro vai se resumir a field=null o que não vai funcionar.

(comentário by Marc B)

Eu faria isto pela claridade.
SELECT *
FROM tbl_name
WHERE 
(id_field IN ('value1', 'value2', 'value3') OR id_field IS NULL)
 67
Author: Daniel A. White, 2017-05-23 11:47:19

A tua pergunta falha devido a precedência do operador. AND liga-se antes de OR!
Você precisa de um par de parênteses, que não é uma questão de "clareza", mas pura necessidade lógica .

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

Os parêntesis adicionados impedem AND a ligação antes de OR. Se não houvesse outras condições WHERE (não AND), não necessitariade parêntesis. A resposta aceite é um pouco enganadora a este respeito.

 14
Author: Erwin Brandstetter, 2017-05-17 17:12:55

A pergunta respondida por Daniel está perfeitamente bem. Queria deixar um bilhete sobre NULLS. Devemos ter o cuidado de não usar no operador quando uma coluna contém valores nulos. Você não vai obter nenhuma saída se a sua coluna contém valores nulos e você está usando o não no operador. É assim que se explica aqui. http://www.oraclebin.com/2013/01/beware-of-nulls.html [3], um artigo muito bom que eu encontrei e pensei em compartilhá-lo.

 6
Author: Sushant Butta, 2017-06-09 08:57:25
SELECT *
FROM tbl_name
WHERE coalesce(id_field,'unik_null_value') 
IN ('value1', 'value2', 'value3', 'unik_null_value')
Para eliminar o nulo do cheque. Dado um valor nulo no id_field, a função coalesce iria em vez do retorno nulo "unik_null_value", e adicionando "unik_null_value" Ao IN-list, a consulta iria retornar posts onde o id_field é valor 1-3 ou nulo.
 5
Author: Ove Halseth, 2016-09-15 06:32:04

Nota: desde que alguém alegou que o link externo está morto na resposta de Sushant Butta eu postei o conteúdo aqui como uma resposta separada.

Cuidado com NULLS.

Hoje deparei-me com um comportamento muito estranho de consulta enquanto utilizava operadores e operadores. Na verdade, eu queria comparar duas tabelas e descobrir se um valor de table b existia em table a ou não e descobrir o seu comportamento se a coluna contém valoresnull. Então eu só ... criou um ambiente para testar este comportamento. Vamos criar a tabela.
SQL> create table table_a ( a number);
Table created.

Vamos criar a tabela table_b.

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

Inserir alguns valores em 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.

Inserir alguns valores em table_b.

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

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

Agora vamos executar uma consulta para verificar a existência de um valor em table_a, verificando o seu valor a partir de table_b usando IN o operador.

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

Executar a pesquisa abaixo para verificar a inexistência.

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

A saída veio como devir. Agora vamos inserir um valor null na tabela table_b e ver como as duas perguntas acima se comportam.

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
A primeira consulta comportou-se como esperado, mas o que aconteceu à segunda? Por que não obtivemos nenhuma saída, o que deveria ter acontecido? Há alguma diferença na consulta? não .

A alteração está nos dados do quadro table_b. Introduzimos um valor null na tabela. Mas porque é que se está a comportar assim? Vamos dividir as duas perguntas em "AND" e "OR" operador.

Primeira Pergunta:

A primeira consulta será tratada internamente algo assim. Assim, um null não irá criar um problema aqui, pois os meus dois primeiros operandos irão avaliar para true ou false. Mas o meu terceiro operando não avaliará a true nem false. Avaliará apenas para 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

Segunda Pesquisa:

A segunda consulta será tratada como se segue. Uma vez que estamos usando um operador "AND" e qualquer outra coisa que não true em qualquer um dos operandes não me dará nenhuma saída.

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
Como lidamos com isto? Vamos escolher todos os valores not null da tabela table_b enquanto usamos o operador NOT IN.
SQL> select * from table_a where a not in (select * from table_b where b is not null);

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

Por isso, tenha sempre cuidado com os valores NULL na coluna, enquanto utiliza o operador NOT IN.

Cuidado com o NULL!!

 1
Author: 1000111, 2017-10-05 07:03:20
Sei que é tarde para responder, mas pode ser útil para outra pessoa. Você pode usar a sub-consulta e converter o nulo para 0
SELECT *
FROM (SELECT CASE WHEN id_field IS NULL 
                THEN 0 
                ELSE id_field 
            END AS id_field
      FROM tbl_name) AS tbl
WHERE tbl.id_field IN ('value1', 'value2', 'value3', 0)
 0
Author: ch2o, 2018-01-24 18:51:16