2012-05-16 21 views
6

tengo esta tabla:comportamiento extraño con NO EN

select count(distinct clean_deep_link) from tbl_1; 
+---------------------------------+ 
| count(distinct clean_deep_link) | 
+---------------------------------+ 
|       121211 | 
+---------------------------------+ 

tengo esta consulta:

select count(1) from tbl_1 where clean_deep_link IN 
    (select clean_deep_link from tbl_2); 

+----------+ 
| count(1) | 
+----------+ 
| 66360 | 
+----------+ 

Pero cuando cambio la consulta a not in devuelve un conjunto vacío:

select count(1) from tbl_1 
where clean_deep_link not in (select clean_deep_link from tbl_2); 
+----------+ 
| count(1) | 
+----------+ 
|  0 | 
+----------+ 

¿Cómo es esto posible? si la subconsulta contiene aproximadamente la mitad de los registros, ¿no debería el not de la subconsulta contener la otra mitad? ¿Que me estoy perdiendo aqui?

Gracias

+0

Pruebe 'SELECT count (*), count (1) DE tbl_1 ... – vyegorov

+0

' ¿Tiene nulos en la columna? ¿Qué devuelve 'SELECT COUNT (*) FROM tbl_1 WHERE clean_deep_link IS NULL'? –

+2

O, en otras palabras, hay tres partes en una tabla SQL. –

Respuesta

9

yo supongo que es tbl_1.clean_deep_linkNULL para el resto de las filas.

Estos valores no son ni IN ni NOT IN su subconsulta.


La otra razón podría ser, que tiene NULL en tbl_2.clean_deep_link.

intenta lo siguiente:

select count(1) from tbl_1 
where clean_deep_link not in (select clean_deep_link 
           from tbl_2 WHERE clean_deep_link IS NOT NULL); 

El problema con NULL es que no es ni =, ni <> cualquier otro valor (incluyendo NULL).

Cuando la comprobación de NOT IN, MySQL necesita comprobar para cada valor de tbl_1 que no está contenida en tbl_2 y por lo tanto comprueba si son <>.

Sus valores fueron no<> NULL, por lo que fueron noNOT IN.

Consulte también: ejemplo Using NOT IN operator with null values


Fecha de SQL Fiddle.

+0

que era el tbl_1 ... – WeaselFox

+0

Sí, había un solo registro en tbl_2 que tenía NULL para clean_deep_link ... cuando quité ese registro, la subconsulta funcionó bien. ¿Cómo pudo haberlo causado? – WeaselFox

+0

Intenté explicarlo en mi actualización reciente, espero que no sea demasiado confuso;) Considere poner una restricción 'NOT NULL' en' tbl_2.clean_deep_link' para evitar este problema. –

2

Las columnas NULL en MySQL se cuentan como distintas, por lo que tres valores NULL se consideran distintos.

Como se mencionó en otra parte, no se puede comparar NULL con otros valores utilizando los operadores de comparación convencionales, entre los que IN y NOT IN.

Los siguientes operadores pueden manejar NULL valores

0
SELECT COUNT(*) - COUNT(1) 
FROM tbl_1 
WHERE clean_deep_link IN (
    SELECT clean_deep_link 
    FROM tbl_2 
); 
Cuestiones relacionadas