ВИБЕРИТЕ * ДЕ НЕ ІСНУЄ


94

Я думаю, що я йду правильним шляхом із цим ... Будь ласка, терпіть зі мною, оскільки мій 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, але це, ймовірно, буде менш ефективним, ніж використання NOT EXISTS.


30
Мені потрібно "ДЕ НЕ ІСНУЄ" двічі на рік, і я завжди забуваю, як саме ним користуватися. Дякую - цей приклад буде додано у закладки.
Mateng

1
Чи може хтось дати посилання на "ЛІВИЙ ПРИЄДНАННЯ + НУЛЬНИЙ фільтр менш ефективний ніж НЕ ІСНУЄ"? Це може бути очевидно, але я ніколи цього не бачив у документах. Дякую.
toni07

2
@ toni07 Насправді це легенда. LEFT JOIN виграє. explainextended.com/2009/09/18 / ... .. блог Quassnoi завжди є корисним ресурсом.
Kaii

як я можу використовувати це в реченні HAVING? akagroup by X having exist [row with employeeID = e.id]
phil294

@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
Примітка! NOT INне працює, як очікувалося, якщо nameмає nullзначення. Дивіться з 36 хв 20 сек у відео СЕССІЯ : 10 технік налаштування запитів, які повинен знати кожен програміст SQL (Кевін Клайн, Аарон Бертран) .
hlovdal

12

Ви можете зробити ЛІВО ПРИЄДНАННЯ і стверджувати, що приєднаний стовпець НУЛЬ.

Приклад:

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

7
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
)

припускаючи, що дві таблиці пов'язані між собою зовнішніми ключовими відносинами. На цьому етапі ви можете використовувати безліч інших варіантів, включаючи ЛІВЕ ПРИЄДНАННЯ. Однак оптимізатор, як правило, обробляє їх однаково в більшості випадків.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.