2012-05-16 15 views
6

Ich habe diese Tabelle:Seltsames Verhalten mit NOT IN

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

Ich habe diese Anfrage:

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

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

Aber wenn ich die Abfrage not in ändern gibt es eine leere Menge:

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

Wie ist das möglich? Wenn die Unterabfrage etwa die Hälfte der Datensätze enthält, sollte nicht die not der Unterabfrage die andere Hälfte enthalten? Was fehlt mir hier?

Dank

+0

Versuchen 'SELECT COUNT (*) handhaben, zählen (1) FROM tbl_1 ...' – vyegorov

+0

Haben Sie nulls in der Spalte haben? Was gibt 'SELECT COUNT (*) FROM tbl_1 WHERE clean_deep_link IS NULL' zurück? –

+2

Oder mit anderen Worten, es gibt drei Hälften in einer SQL-Tabelle. –

Antwort

9

Ich würde davon ausgehen, dass tbl_1.clean_deep_linkNULL für den Rest der Zeilen ist. Diese Werte sind weder IN noch NOT IN Ihre Unterabfrage.


Der andere Grund könnte sein, dass Sie NULL in tbl_2.clean_deep_link haben.

Bitte versuchen Sie folgendes:

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); 

Das Problem mit NULL ist, dass es weder =, noch <> einen anderen Wert (einschließlich NULL) ist.

Wenn für NOT IN Überprüfung muss MySQL für jeden Wert in tbl_1 überprüfen, die es nicht in tbl_2 und damit Kontrollen enthalten ist, wenn sie <> sind.

waren Ihre Werte nicht<> NULL, so waren sie nichtNOT IN. auch

Siehe: Using NOT IN operator with null values


prüfen Beispiel in SQL Fiddle.

+0

war der tbl_1 ... – WeaselFox

+0

Ja, es gab einen einzigen Datensatz in tbl_2, der NULL für clean_deep_link hatte ... als ich diesen Datensatz entfernt hatte, funktionierte die Unterabfrage gut. Wie konnte das das verursacht haben? – WeaselFox

+0

Versucht, es in meinem letzten Update zu erklären, hoffe, es ist nicht zu verwirrend;) Überlegen Sie, eine 'NOT NULL' Einschränkung auf' tbl_2.clean_deep_link' zu setzen, um dieses Problem zu vermeiden. –

2

Die Spalten in MySQL werden als unterschiedlich gezählt, so dass drei NULL Werte alle als unterschiedlich angesehen werden.

Wie bereits an anderer Stelle erwähnt, können Sie NULL nicht mit anderen Werten vergleichen, die herkömmliche Vergleichsoperatoren verwenden, darunter IN und NOT IN.

Die folgenden Operatoren können NULL Werte

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