Jak wybrać wszystkie rekordy z jednej tabeli, które nie istnieją w innej tabeli?

Table1 (id, Nazwa)
table2 (id, name)

Zapytanie:

SELECT name   
FROM table2  
-- that are not in table1 already
Author: z-boss, 2010-04-22

9 answers

SELECT t1.name
FROM table1 t1
LEFT JOIN table2 t2 ON t2.name = t1.name
WHERE t2.name IS NULL

P: co tu się dzieje?

A : koncepcyjnie wybieramy wszystkie wiersze z table1 i dla każdego wiersza próbujemy znaleźć wiersz w table2 z taką samą wartością dla kolumny name. Jeśli nie ma takiego wiersza, zostawiamy table2 część naszego wyniku pustą dla tego wiersza. Następnie ograniczamy nasz wybór, wybierając tylko te wiersze w wyniku, w których pasujący wiersz nie istnieje. Na koniec ignorujemy wszystkie pola z naszego wyniku z wyjątkiem Kolumny name (tej jesteśmy pewni, że istnieje, z table1).

Chociaż może nie być to najbardziej wydajna metoda możliwa we wszystkich przypadkach, powinna działać w zasadzie w każdym silniku bazy danych, który próbuje zaimplementować ANSI 92 SQL

 605
Author: Kris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-29 09:00:35

Możesz albo zrobić

SELECT name
FROM table2
WHERE name NOT IN
    (SELECT name 
     FROM table1)

Lub

SELECT name 
FROM table2 
WHERE NOT EXISTS 
    (SELECT * 
     FROM table1 
     WHERE table1.name = table2.name)

Zobacz to pytanie dla 3 technik, aby to osiągnąć

 176
Author: froadie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-20 09:19:32

Nie mam wystarczającej ilości punktów rep, aby zagłosować na drugą odpowiedź. Ale muszę się nie zgadzać z komentarzami na górze odpowiedzi. Druga odpowiedź:

SELECT name
FROM table2
WHERE name NOT IN
    (SELECT name 
     FROM table1)

Jest znacznie bardziej efektywny w praktyce. Nie wiem dlaczego, ale ja go uruchamiam z rekordami 800k+ i różnica jest ogromna z przewagą nad 2. odpowiedzią zamieszczoną powyżej. Tylko moje $0.02

 56
Author: Tan Rezaei,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-07 20:31:27

Jest to czysta teoria mnogości, którą można osiągnąć za pomocą operacji minus.

select id, name from table1
minus
select id, name from table2
 32
Author: Winter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-14 12:33:06

Uważaj na pułapki. Jeśli pole Name w Table1 zawiera null, czeka cię niespodzianka. Lepiej jest:

SELECT name
FROM table2
WHERE name NOT IN
    (SELECT ISNULL(name ,'')
     FROM table1)
 13
Author: user4872693,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-06 23:35:48

Możesz użyć EXCEPT w mssql lub MINUS w oracle, są one identyczne zgodnie z:

Http://blog.sqlauthority.com/2008/08/07/sql-server-except-clause-in-sql-server-is-similar-to-minus-clause-in-oracle/

 8
Author: Izzy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-16 15:57:33

Oto, co dla mnie najlepsze.

SELECT *
FROM @T1
EXCEPT
SELECT a.*
FROM @T1 a
JOIN @T2 b ON a.ID = b.ID
To było ponad dwa razy szybciej niż jakakolwiek inna metoda, którą próbowałem.
 8
Author: Bob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-30 01:46:31

That work sharp for me

SELECT * 
FROM [dbo].[table1] t1
LEFT JOIN [dbo].[table2] t2 ON t1.[t1_ID] = t2.[t2_ID]
WHERE t2.[t2_ID] IS NULL
 6
Author: David Fawzy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-29 15:40:39

Zamierzam odświeżyć (ponieważ nie jestem na tyle fajny, aby skomentować) w poprawnej answer....in gdyby ktoś inny pomyślał, że trzeba to lepiej wyjaśnić.

SELECT temp_table_1.name
FROM original_table_1 temp_table_1
LEFT JOIN original_table_2 temp_table_2 ON temp_table_2.name = temp_table_1.name
WHERE temp_table_2.name IS NULL

I widziałem składnię z konieczności przecinków między nazwami tabel w mySQL, ale w sqlLite wydawało się preferować spację.

Najważniejsze jest to, że gdy używasz złych nazw zmiennych, pozostawia pytania. Moje zmienne powinny mieć więcej sensu. I ktoś powinien wyjaśnić, dlaczego potrzebujemy przecinka lub nie przecinka.

 -2
Author: Adrian Roth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-16 02:45:38