Как выбрать все записи из одной таблицы, которые не существуют в другой таблице? - PullRequest
385 голосов
/ 22 апреля 2010

table1 (id, name)
table2 (id, name)

Запрос:

SELECT name   
FROM table2  
-- that are not in table1 already

Ответы [ 10 ]

721 голосов
/ 22 апреля 2010
SELECT t1.name
FROM table1 t1
LEFT JOIN table2 t2 ON t2.name = t1.name
WHERE t2.name IS NULL

Q : Что здесь происходит?

A : Концептуально мы выбираем все строки из table1, и для каждой строки мы пытаемся найти строку в table2 с тем же значением для столбца name. Если такой строки нет, мы просто оставляем часть table2 нашего результата пустой для этой строки. Затем мы ограничиваем наш выбор, выбирая только те строки в результате, где соответствующая строка не существует. Наконец, мы игнорируем все поля из нашего результата, кроме столбца name (который, как мы уверены, существует, начиная с table1).

Хотя это может быть не самый производительный метод, возможный во всех случаях, он должен работать практически в каждом механизме баз данных, когда-либо пытающемся реализовать ANSI 92 SQL

206 голосов
/ 22 апреля 2010

Вы можете выполнить

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

или

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

См. в этом вопросе о 3 методах для выполнения этого

65 голосов
/ 24 января 2014

Мне не хватает точек репутации, чтобы проголосовать за второй ответ. Но я должен не согласиться с комментариями на верхний ответ. Второй ответ:

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

Является ли FAR более эффективным на практике. Я не знаю почему, но я работаю с 800k + записями, и разница огромна с преимуществом, полученным во втором ответе, опубликованном выше. Просто мои $ 0,02

35 голосов
/ 22 апреля 2010

Это чистая теория множеств, которую вы можете достичь с помощью операции minus.

select id, name from table1
minus
select id, name from table2
15 голосов
/ 23 ноября 2018
SELECT <column_list>
FROM TABLEA a
LEFTJOIN TABLEB b 
ON a.Key = b.Key 
WHERE b.Key IS NULL;

enter image description here

https://www.cloudways.com/blog/how-to-join-two-tables-mysql/

14 голосов
/ 07 мая 2015

Остерегайтесь ловушек. Если поле Name в Table1 содержит пустые значения, вас ждут сюрпризы. Лучше это:

SELECT name
FROM table2
WHERE name NOT IN
    (SELECT ISNULL(name ,'')
     FROM table1)
13 голосов
/ 30 ноября 2016

Вот что сработало для меня лучше всего.

SELECT *
FROM @T1
EXCEPT
SELECT a.*
FROM @T1 a
JOIN @T2 b ON a.ID = b.ID

Это было в два раза быстрее, чем любой другой метод, который я пробовал.

8 голосов
/ 16 ноября 2015

Вы можете использовать EXCEPT в mssql или MINUS в oracle, они идентичны согласно:

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

7 голосов
/ 21 сентября 2016

Это работа для меня

SELECT * 
FROM [dbo].[table1] t1
LEFT JOIN [dbo].[table2] t2 ON t1.[t1_ID] = t2.[t2_ID]
WHERE t2.[t2_ID] IS NULL
0 голосов
/ 16 августа 2018

Я собираюсь сделать репост (поскольку я еще недостаточно крут, чтобы комментировать) в правильном ответе .... на тот случай, если кто-то еще подумает, что лучше объяснить.

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

И яВы видели синтаксис в FROM, нуждающийся в запятых между именами таблиц в mySQL, но в sqlLite казалось, что он предпочитает пробел.

Суть в том, что при использовании неверных имен переменных возникают вопросы.Мои переменные должны иметь больше смысла.И кто-то должен объяснить, почему нам нужна запятая или нет запятой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...