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?
6 answers
Uma declaração
in
será analisada de forma idêntica afield=val1 or field=val2 or field=val3
. Colocar um null lá dentro vai se resumir afield=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)
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.
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.
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.
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 detable 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!!
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)