table1 (id, name)
table2 (id, name)
Query:
SELECT name
FROM table2
-- that are not in table1 already
table1 (id, name)
table2 (id, name)
Query:
SELECT name
FROM table2
-- that are not in table1 already
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
Вы можете сделать
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 методов для достижения этой цели
У меня нет достаточного количества очков для голосования по 2-му ответу. Но я должен не согласиться с комментариями на верхний ответ. Второй ответ:
SELECT name
FROM table2
WHERE name NOT IN
(SELECT name
FROM table1)
Является ли FAR более эффективным на практике. Я не знаю, почему, но я запускаю его с записями 800k +, и разница огромна с преимуществом, предоставленным второму ответу, опубликованному выше. Только мои $0.02
Это чистая теория множеств, которую вы можете достичь с помощью операции minus
.
select id, name from table1
minus
select id, name from table2
SELECT <column_list>
FROM TABLEA a
LEFTJOIN TABLEB b
ON a.Key = b.Key
WHERE b.Key IS NULL;
https://www.cloudways.com/blog/how-to-join-two-tables-mysql/
Следите за подводными камнями. Если поле Name
в Table1
содержит Nulls, вы попадаете в сюрпризы.
Лучше:
SELECT name
FROM table2
WHERE name NOT IN
(SELECT ISNULL(name ,'')
FROM table1)
Вот что сработало лучше для меня.
SELECT *
FROM @T1
EXCEPT
SELECT a.*
FROM @T1 a
JOIN @T2 b ON a.ID = b.ID
Это было более чем в два раза быстрее, чем любой другой метод, который я пробовал.
Вы можете использовать EXCEPT
в mssql или MINUS
в oracle, они идентичны в соответствии с:
Это работает для меня.
SELECT *
FROM [dbo].[table1] t1
LEFT JOIN [dbo].[table2] t2 ON t1.[t1_ID] = t2.[t2_ID]
WHERE t2.[t2_ID] IS NULL
Итак, я протестировал с базой данных более 4 миллионов записей (varchar) и вот мой результат: таблица 1 - 1,8 миллиона записей, таблица 2 - 4 миллиона записей
1) select count(*) from table1 a LEFT JOIN table2 b on a.id = b.id
where b.id IS NULL
Took 12.68 secs
2) select count(*) from table1 a WHERE NOT EXISTS (select * from table2 b where a.id = b.id )
Took 17.11 secs
3) select count(*) from table1
where id NOT IN (select id from table2)
Took over 3 minutes so i had to CTRL-C to cancel
Так что я полностью согласен с первым ответом
Смотрите запрос:
SELECT * FROM Table1 WHERE
id NOT IN (SELECT
e.id
FROM
Table1 e
INNER JOIN
Table2 s ON e.id = s.id);
Концептуально было бы: выборка соответствующих записей в подзапросе, а затем в основном запросе выборка записей, которые не находятся в подзапросе.
Я собираюсь сделать репост (так как я еще не настолько крут, чтобы комментировать) в правильном ответе.... на тот случай, если кто-то еще подумает, что лучше объяснить.
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 казалось, что он предпочитает пробел.
Суть в том, что когда вы используете неверные имена переменных, это оставляет вопросы. Мои переменные должны иметь больше смысла. И кто-то должен объяснить, почему нам нужна запятая или нет запятой.