Mam dwie tabele z powiązanym kluczem podstawowym w bazie danych i chcę znaleźć rozłączny zestaw między nimi. Na przykład,
Table1
zawiera kolumny (ID, Name
) i przykładowe dane:(1 ,John), (2, Peter), (3, Mary)
Table2
zawiera kolumny (ID, Address
) i przykładowe dane:(1, address2), (2, address2)
Jak więc utworzyć zapytanie SQL, aby pobrać wiersz z identyfikatorem, table1
którego nie ma w table2
. W takim razie (3, Mary)
należy zwrócić?
Ps. Identyfikator jest kluczem podstawowym dla tych dwóch tabel.
Z góry dziękuję.
sql
database
postgresql
johnklee
źródło
źródło
Odpowiedzi:
Spróbuj tego
źródło
Posługiwać się
LEFT JOIN
źródło
Istnieją 3 sposoby na to:
not exists
,not in
ileft join / is null
.LEFT JOIN z IS NULL
NIE W
NIE ISTNIEJE
Który jest lepszy? Odpowiedź na to pytanie mogłaby być lepsza, gdyby została podzielona na głównych, konkretnych dostawców RDBMS. Ogólnie rzecz biorąc, należy unikać stosowania,
select ... where ... in (select...)
gdy wielkość liczby rekordów w zapytaniu podrzędnym jest nieznana. Niektórzy dostawcy mogą ograniczać rozmiar. Na przykład Oracle ma limit 1000 . Najlepiej jest wypróbować wszystkie trzy i pokazać plan wykonania.W szczególności z PostgreSQL, plan wykonania
NOT EXISTS
iLEFT JOIN / IS NULL
są takie same. Osobiście wolę tęNOT EXISTS
opcję, ponieważ lepiej pokazuje zamiar. Po tym wszystkim jest to, że semantyczna chcesz znaleźć rekordy w pk że nie istnieją w B .Stary, ale wciąż złoty, specyficzny dla PostgreSQL: https://explainextended.com/2009/09/16/not-in-vs-not-exists-vs-left-join-is-null-postgresql/
źródło
Szybka alternatywa
Przeprowadziłem kilka testów (na postgres 9.5) używając dwóch tabel z ~ 2M wierszami każda. Poniższe zapytanie było co najmniej 5 * lepsze niż pozostałe proponowane zapytania:
źródło
Mając na uwadze uwagi przedstawione w komentarzu / linku @John Woo powyżej, zazwyczaj radziłbym sobie z tym w następujący sposób:
źródło
źródło