En la cláusula con NULL o ES NULL


Postgres es la base de datos

¿Puedo usar un valor NULL para una cláusula IN? ejemplo:

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

Quiero limitar a estos cuatro valores.

He probado la sentencia anterior y no funciona, bien se ejecuta pero no agrega los registros con id_fields NULL.

También he intentado agregar una condición OR, pero esto solo hace que la consulta se ejecute y se ejecute sin fin a la 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

Alguna sugerencia?

Author: Phill Pafford, 2011-06-15

6 answers

Una instrucción in se analizará de forma idéntica a field=val1 or field=val2 or field=val3. Poner un null allí se reducirá a field=null que no funcionará.

(Comentario por Marc B)

Haría esto por clairity

SELECT *
FROM tbl_name
WHERE 
(id_field IN ('value1', 'value2', 'value3') OR id_field IS NULL)
 67
Author: Daniel A. White,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:19

Su consulta falla debido a precedencia del operador. AND se une antes de OR!
Se necesita un par de paréntesis, que no es una cuestión de "claridad", sino pura necesidad 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)

Los paréntesis añadidos impiden AND el enlace antes de OR. Si no hubiera otras condiciones WHERE (no AND), no necesitaría paréntesis. La respuesta aceptada es un poco engañosa a este respecto.

 14
Author: Erwin Brandstetter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-17 17:12:55

La pregunta respondida por Daniel está perfectamente bien. Quería dejar una nota sobre los NULOS. Debemos ser cuidadosos con el uso del operador NOT IN cuando una columna contiene valores NULOS. No obtendrá ninguna salida si su columna contiene valores NULOS y está utilizando el operador NOT IN. Así es como se explica aquí http://www.oraclebin.com/2013/01/beware-of-nulls.html , un artículo muy bueno que me encontré y pensé en compartirlo.

 6
Author: Sushant Butta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
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 el null de la comprobación. Dado un valor null en id_field, la función coalesce en lugar de null devolvería 'unik_null_value', y al agregar ' unik_null_value a la lista, la consulta devolvería mensajes donde id_field es value1-3 o null.

 5
Author: Ove Halseth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-15 06:32:04

Nota: Desde que alguien afirmó que el enlace externo está muerto en La respuesta de Sushant Butta he publicado el contenido aquí como una respuesta separada.

Tenga cuidado conNULLS .

Hoy me encontré con un comportamiento muy extraño de consulta al usar IN y NOT IN operadores. En realidad quería comparar dos tablas y averiguar si un valor de table b existía en table a o no y averiguar su comportamiento si la columna contiene valoresnull. Así que sólo se creó un entorno para probar este comportamiento.

Crearemos la tabla table_a.

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

Crearemos la tabla table_b.

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

Inserte algunos valores en 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.

Inserte algunos valores en table_b.

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

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

Ahora ejecutaremos una consulta para comprobar la existencia de un valor en table_a comprobando su valor desde table_b usando el operador IN.

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

Ejecute la siguiente consulta para comprobar la inexistencia.

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

La salida vino como previsto. Ahora insertaremos un valor null en la tabla table_b y veremos cómo se comportan las dos consultas anteriores.

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

La primera consulta se comportó como se esperaba, pero ¿qué pasó con la segunda consulta? ¿Por qué no obtuvimos ninguna salida, qué debería haber pasado? Hay alguna diferencia en la consulta? No .

El cambio está en los datos de la tabla table_b. Hemos introducido un valor null en la tabla. ¿Pero cómo es que se comporta así? Dividamos las dos consultas en "AND" y "OR" operador.

Primera consulta:

La primera consulta será manejada internamente algo como esto. Así que un null no creará un problema aquí ya que mis dos primeros operandos evaluarán a true o false. Pero mi tercer operando a = null no evaluará a true ni false. Se evaluará a null solamente.

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 pregunta:

La segunda consulta se manejará de la siguiente manera. Dado que estamos utilizando un operador "AND" y cualquier otra cosa que true en cualquiera de los operando no me dará ninguna salida.

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

Entonces, ¿cómo manejamos esto? Elegiremos todos los valores not null de la tabla table_b mientras usamos el operador NOT IN.

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

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

Así que siempre tenga cuidado con los valores NULL en la columna mientras usa el operador NOT IN.

Cuidado con NULL!!

 1
Author: 1000111,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-05 07:03:20

Sé que es tarde para responder, pero podría ser útil para alguien más Puede utilizar sub-consulta y convertir el null a 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,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-24 18:51:16