ВЫБРАТЬ * ГДЕ НЕ СУЩЕСТВУЕТ

95

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

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

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

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

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

Кто-нибудь может помочь?

Кьяран
источник

Ответы:

160

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

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

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

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

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

Quassnoi
источник
30
Мне нужно «ГДЕ НЕ СУЩЕСТВУЕТ» дважды в год, и я всегда забываю, как именно им пользоваться. Спасибо - этот пример сейчас будет добавлен в закладки.
Mateng,
1
Может ли кто-нибудь дать ссылку на «фильтр LEFT JOIN + NULL менее эффективен, чем НЕ СУЩЕСТВУЕТ»? Это может быть очевидно, но я никогда не видел этого в документации. Спасибо.
toni07
2
@ toni07 Вообще-то, это легенда. LEFT JOIN побеждает. объяснятьextended.com/ 2009/09/18/… .. Блог Quassnoi всегда является полезным ресурсом.
Kaii
как мне использовать это в предложении HAVING? akagroup by X having exist [row with employeeID = e.id]
phil294 07
@blauhirn: вот так
Quassnoi
83
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
День Робина
источник
1
NB! NOT INне работает должным образом, если nameимеет nullзначения. Смотрите видеоролик « СЕССИЯ: 10 методов настройки запросов, которые должен знать каждый программист SQL» (Кевин Клайн, Аарон Бертран) .
hlovdal 02
12

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

Пример:

SELECT * FROM employees a LEFT JOIN eotm_dyn b on (a.joinfield=b.joinfield) WHERE b.name IS NULL
Майк Танниклифф
источник
8
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

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

Андре Миллер
источник