НЕ СУЩЕСТВУЕТ предложение в SQL

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

Запрос разработан, чтобы найти детали сотрудника, который работает над всеми проектами.

Запрос:

SELECT E.LNAME, E.FNAME
FROM EMPLOYEE E
WHERE NOT EXISTS
(
    SELECT PNUMBER
    FROM PROJECT
    WHERE PNUMBER NOT EXISTS 
    (
        SELECT PNO 
        FROM WORKS_ON
        WHERE ESSN=E.SSN 
    ) 
);

Структура БД:

Таблица проектов с колонками:

Pname,Pnumber,Plocation и dnum

Таблица works_on со столбцами:

ESSN,PNO и ЧАСЫ

Таблица Employee с колонками:

Fname, minit, Lname, SSN, Bdate, адрес, пол, зарплата, суперссн и днно

Если кто-то может объяснить простыми словами, как выполняется этот запрос, это будет действительно полезно.

3 ответа

Условие SQL EXISTS считается выполненным, если подзапрос возвращает хотя бы одну строку.

Поэтому, подразумевая NOT EXISTS, мы хотим, чтобы подзапрос возвратил ноль строк, поэтому с этим знанием давайте посмотрим на ваш запрос.

SELECT E.LNAME, E.FNAME
FROM EMPLOYEE E
WHERE NOT EXISTS (SELECT PNUMBER
FROM PROJECT
WHERE PNUMBER NOT EXISTS (SELECT PNO 
FROM WORKS_ON
WHERE ESSN=E.SSN ) );

Есть два вложенных оператора NOT EXISTS, и SQL придется запускать их в обратном порядке, потому что один зависит от другого. Первый, который будет запрошен, это (последний):

SELECT PNO 
    FROM WORKS_ON
    WHERE ESSN=E.SSN

Если это возвращает ноль строк (потому что мы сказали НЕ СУЩЕСТВУЕТ), то он выполнит следующий запрос, который будет:

SELECT PNUMBER
    FROM PROJECT

Опять же, это должно вернуть ноль строк, и если это произойдет, то он выполнит последний запрос, который является первым.

SELECT E.LNAME, E.FNAME
FROM EMPLOYEE E

По сути, каждый подзапрос "НЕ СУЩЕСТВУЕТ" должен возвращать ноль строк для выполнения предыдущего запроса, в противном случае вы получите 0 строк (без результатов).

Больше информации о СУЩЕСТВОВАНИИ здесь

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

Прежде всего, я не знаю синтаксис внутреннего <column name> NOT EXISTS <subquery> но это похоже на <column name> NOT IN <subquery>, Именно это понятие сделало запрос более полным для меня, потому что он более четко связывает внутренний запрос с ПРОЕКТОМ.
Итак, я начал с

SELECT E.LNAME, E.FNAME
FROM EMPLOYEE E
WHERE NOT EXISTS
(
    SELECT PNUMBER
    FROM PROJECT
    WHERE PNUMBER NOT IN
    (
        SELECT PNO
        FROM WORKS_ON
        WHERE ESSN=E.SSN
    )
);

Разбивка шагов:

  • Внутренний запрос просто перечисляет все номера проектов, над которыми работает ваш сотрудник.

            SELECT PNO
            FROM WORKS_ON
            WHERE ESSN=E.SSN
    
  • Средний запрос принимает дополнение. Результатом являются все номера проектов, над которыми ваш сотрудник не работает.

        SELECT PNUMBER
        FROM PROJECT
        WHERE PNUMBER NOT IN
        (
            -- projects that the employee works on
        )
    
  • Если существуют проекты, в которых сотрудник не работает, то он работает не над всеми из них, и поэтому его не следует включать в результаты.

    SELECT E.LNAME, E.FNAME
    FROM EMPLOYEE E
    WHERE NOT EXISTS
    (
        -- projects that the employee does not work on
    )
    

Ответ от KeyszerS достаточно для этого вопроса. Однако я хотел бы добавить еще несколько пунктов

Выполнение SQL-запроса начинается с внутреннего запроса. Следовательно, в вашем запросе тот, в котором предложение сначала выполняется

ГДЕ ПНУМЕР НЕ СУЩЕСТВУЕТ (ВЫБЕРИТЕ PNO ИЗ WORKS_ON, ГДЕ ESSN = E.SSN)

на основе результата вышеупомянутого запроса будет выполнен другой запрос ниже.

WHERE NOT EXISTS (
    SELECT PNUMBER
    FROM PROJECT
    WHERE PNUMBER NOT EXISTS (**Resultset**)

Подводя итог моей точке зрения - вам нужно отладить ваш запрос на основе результатов в подзапросах.

Другие вопросы по тегам