Próbuję wykonać to zapytanie:
SELECT mac, creation_date
FROM logs
WHERE logs_type_id=11
AND mac NOT IN (select consols.mac from consols)
Ale nie mam żadnych wyników. Przetestowałem to i wiem, że jest coś nie tak ze składnią. W MySQL takie zapytanie działa doskonale. Dodałem wiersz, aby upewnić się, że istnieje taki, mac
którego nie ma w consols
tabeli, ale nadal nie daje żadnych wyników.
postgresql
subquery
skowron-line
źródło
źródło
consols.mac
kolumna jestNULL
czyNOT NULL
?Odpowiedzi:
Korzystając z opcji NOT IN, należy upewnić się, że żadna z wartości nie jest NULL:
SELECT mac, creation_date FROM logs WHERE logs_type_id=11 AND mac NOT IN ( SELECT mac FROM consols WHERE mac IS NOT NULL -- add this )
źródło
WHERE mac IS NOT NULL
klauzula w podzapytaniu nie jest potrzebna, ponieważIn(...)
zawsze usuwa wartości NULL (i duplikaty). Ponieważ zestaw nie może zawierać wartości NULLIS NOT NULL
. ZagnieżdżonySELECT
zwracał kilkaNULLS
, a to było potknięcie sięIN(SELECT...)
.IS NOT NULL
to działa.NULL
wNOT IN
klauzuli nie działa, ponieważ porównanie doNULL
nie jest ani prawdziwe, ani fałszywe. sqlbadpractices.com/using-not-in-operator-with-null-valuesis not null
jeśli podzapytanie nie zwróci żadnych pasujących wartości i co najmniej jednejnull
wartości. Z sekcji 9.22 bieżącego podręcznika PostgreSQL (wersja 10): „[…] jeśli nie ma równych wartości po prawej stronie i co najmniej jeden wiersz po prawej stronie daje wartość null, wynik konstrukcji NOT IN będzie miał wartość NULL, nie prawda ”.Korzystając z opcji NOT IN, należy również rozważyć opcję NOT EXISTS, która po cichu obsługuje przypadki zerowe. Zobacz także PostgreSQL Wiki
SELECT mac, creation_date FROM logs lo WHERE logs_type_id=11 AND NOT EXISTS ( SELECT * FROM consols nx WHERE nx.mac = lo.mac );
źródło
NOT EXISTS
vs... NOT IN
Możesz również użyć warunku LEFT JOIN i IS NULL:
SELECT mac, creation_date FROM logs LEFT JOIN consols ON logs.mac = consols.mac WHERE logs_type_id=11 AND consols.mac IS NULL;
Indeks w kolumnach „mac” może poprawić wydajność.
źródło