2009-05-27 5 views
67

Я думаю, что я иду по правильному пути с этого ... Пожалуйста, медведь со мной, как мой SQL не является самым большимSELECT * WHERE NOT EXISTS

Я пытаюсь сделать запрос к базе данных, чтобы выбрать все из одной таблицы, где определенные ячейки не существуют в другом. Это много не делает много смысла, но я надеюсь, что этот кусок кода будет

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

Так в основном у меня есть одна таблица со списком сотрудников и их деталей. Затем еще один стол с некоторыми другими деталями, включая их имя. Там, где имя отсутствует в таблице eotm_dyn, то есть нет записи для них, я хотел бы точно узнать, кто они, или, другими словами, посмотреть, что именно отсутствует.

Вышеприведенный запрос ничего не возвращает, но я знаю, что имена 20ish отсутствуют, поэтому я, очевидно, не получил это правильно.

Может ли кто-нибудь помочь?

ответ

105

Вы не присоединились к таблице в своем запросе.

Ваш исходный запрос всегда будет возвращать ничего, если нет записей вообще в eotm_dyn, и в этом случае он вернет все.

Предполагая, что эти таблицы должны быть сдвинуты по employeeID, используйте следующее:

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

Вы можете присоединиться к этим таблицам с LEFT JOIN ключевого слова и отфильтровать NULL «с, но это, вероятно, будет менее эффективным, чем использование NOT EXISTS.

+21

Мне нужно «ГДЕ НЕ СУЩЕСТВУЕТ» два раза в год, и я всегда забываю, как точно его использовать. Спасибо - этот пример будет теперь отмечен закладкой. – Mateng

+1

Может ли кто-нибудь дать ссылку на "LEFT JOIN + NULL фильтр менее эффективен, чем НЕ СУЩЕСТВУЕТ"? Это может быть очевидно, но я никогда не видел этого в документах. Благодарю. – toni07

+1

@ toni07 Собственно, это легенда. Победа в LEFT JOIN.https://explainextended.com/2009/09/18/not-in-vs-not-exists-vs-left-join-is-null-mysql/ .. Блог Quassnoi всегда является полезным ресурсом. – Kaii

11

Вы можете сделать LEFT JOIN и утверждать, что объединенный столбец равен NULL.

Пример:

SELECT * FROM employees a LEFT JOIN eotm_dyn b on (a.joinfield=b.joinfield) WHERE b.name IS NULL 
68
SELECT * FROM employees WHERE name NOT IN (SELECT name FROM eotm_dyn) 

ИЛИ

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

ИЛИ

SELECT * FROM employees LEFT OUTER JOIN eotm_dyn ON eotm_dyn.name = employees.name WHERE eotm_dyn IS NULL 
+0

NB! 'NOT IN' не работает должным образом, если' name'has 'null'values. Смотреть от 36 минут 20 секунд в видео [СЕССИЯ: 10 методов настройки запросов Каждый программист SQL должен знать (Кевин Клайн, Аарон Бертран)] (https://www.youtube.com/watch?v=XUCxQkFoqpw). – hlovdal

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

Никогда не возвращает никаких записей, если eotm_dyn пуст. Вы должны каким-то критериям на SELECT name FROM eotm_dyn как

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

при условии, что эти две таблицы связаны между собой с помощью внешнего ключа отношения. На этом этапе вы можете использовать множество других опций, включая LEFT JOIN. Однако оптимизатор, как правило, обрабатывает их в большинстве случаев.

4

Вы также можете взглянуть на this related question. Этот пользователь сообщил, что использование соединения обеспечивает лучшую производительность, чем использование вспомогательного запроса.

Смежные вопросы