WYBIERZ * GDZIE NIE ISTNIEJE

96

Myślę, że z tym podążam właściwą ścieżką ... Proszę o wyrozumiałość, ponieważ mój SQL nie jest najlepszy

Próbuję wysłać zapytanie do bazy danych, aby wybrać wszystko z jednej tabeli, w której określone komórki nie istnieją w innej. To nie ma większego sensu, ale mam nadzieję, że ten fragment kodu będzie

SELECT * from employees WHERE NOT EXISTS (SELECT name FROM eotm_dyn)

Zasadniczo mam jedną tabelę z listą pracowników i ich danymi. Następnie kolejna tabela z innymi szczegółami, w tym ich nazwą. Tam, gdzie w tabeli eotm_dyn nie ma nazwy, co oznacza, że ​​nie ma dla nich wpisu, chciałbym zobaczyć dokładnie, kim są, czyli innymi słowy, zobaczyć, czego dokładnie brakuje.

Powyższe zapytanie nic nie zwraca, ale wiem, że brakuje 20 nazwisk, więc najwyraźniej nie zrozumiałem tego poprawnie.

Czy ktoś może pomóc?

Ciaran
źródło

Odpowiedzi:

163

Nie dołączyłeś do tabeli w swoim zapytaniu.

Twoje pierwotne zapytanie zawsze nic nie zwróci, chyba że w ogóle nie ma żadnych rekordów eotm_dyn W takim przypadku zwróci wszystko.

Zakładając, że te tabele powinny być połączone employeeID, użyj następującego:

SELECT  *
FROM    employees e
WHERE   NOT EXISTS
        (
        SELECT  null 
        FROM    eotm_dyn d
        WHERE   d.employeeID = e.id
        )

Możesz połączyć te tabele za pomocą LEFT JOINsłowa kluczowego i odfiltrować tabele NULL, ale prawdopodobnie będzie to mniej wydajne niż użycie NOT EXISTS.

Quassnoi
źródło
31
Potrzebuję „GDZIE NIE ISTNIEJE” dwa razy w roku i zawsze zapominam, jak go dokładnie użyć. Dzięki - ten przykład zostanie teraz dodany do zakładek.
Mateng,
1
Czy ktoś mógłby podać odniesienie do stwierdzenia „LEFT JOIN + NULL filtr jest mniej wydajny niż NIE ISTNIEJE”? To może być oczywiste, ale nigdy nie widziałem tego w dokumentach. Dzięki.
toni07
2
@ toni07 Właściwie to jest legenda. LEFT JOIN wygrywa. wyjaśnienie.com/2009/ 09/18/… .. Blog Quassnoi jest zawsze pomocnym źródłem informacji.
Kaii
jak użyłbym tego w klauzuli HAVING? akagroup by X having exist [row with employeeID = e.id]
phil294
@blauhirn: tak po prostu
Quassnoi
84
SELECT * FROM employees WHERE name NOT IN (SELECT name FROM eotm_dyn)

LUB

SELECT * FROM employees WHERE NOT EXISTS (SELECT * FROM eotm_dyn WHERE eotm_dyn.name = employees.name)

LUB

SELECT * FROM employees LEFT OUTER JOIN eotm_dyn ON eotm_dyn.name = employees.name WHERE eotm_dyn IS NULL
Robin Day
źródło
1
NB! NOT INnie działa zgodnie z oczekiwaniami, jeśli namema nullwartości. Obejrzyj wideo od 36 min do 20 s. SESJA: 10 technik dostrajania zapytań, które powinien znać każdy programista SQL (Kevin Kline, Aaron Bertrand) .
hlovdal
12

Możesz wykonać LEFT JOIN i potwierdzić, że połączona kolumna ma wartość NULL.

Przykład:

SELECT * FROM employees a LEFT JOIN eotm_dyn b on (a.joinfield=b.joinfield) WHERE b.name IS NULL
Mike Tunnicliffe
źródło
8
SELECT * from employees
WHERE NOT EXISTS (SELECT name FROM eotm_dyn)

Nigdy nie zwraca żadnych rekordów, chyba że eotm_dynjest pusta. Musisz mieć jakieś kryteria na SELECT name FROM eotm_dynpolubienie

SELECT * from employees
WHERE NOT EXISTS (
    SELECT name FROM eotm_dyn WHERE eotm_dyn.employeeid = employees.employeeid
)

zakładając, że dwie tabele są połączone relacją klucza obcego. W tym momencie możesz skorzystać z wielu innych opcji, w tym LEFT JOIN. Jednak w większości przypadków optymalizator będzie obsługiwał je w ten sam sposób.

Cade Roux
źródło
4

Możesz również rzucić okiem na to powiązane pytanie . Ten użytkownik zgłosił, że użycie sprzężenia zapewniło lepszą wydajność niż użycie zapytania podrzędnego.

Andre Miller
źródło