SQL выглядит нормально.
Чтобы ответить на ваш актуальный вопрос: «Но почему-то мне не хватает того, как происходит оценка для таких запросов».
Что происходит концептуально заключается в том, что самый внешний выбор [FROM STUDENT AS S] охватывает всех учащихся по одному, каждый раз сохраняя значения атрибута из текущей строки в контексте для дальнейшего использования.
Тогда самое внешнее, ГДЕ НЕ СУЩЕСТВУЕТ, сканирует все курсы [ВЫБРАТЬ ИЗ КУРСА] один за другим, в результате чего значения атрибутов из «текущей» строки снова сохраняются в контексте для дальнейшей ссылки [так что теперь у нас есть оба «текущий» ряд студентов, а также «текущий» ряд курсов].
Тогда самый внутренний ГДЕ НЕ СУЩЕСТВУЕТ, проверяя, есть ли зачисление для ученика из контекста и курса из контекста. Если нет, то есть курс, на который студент не зачислен, так что конкретный студент не следует всем курсам.
Я подчеркнул концептуально , и я подчеркну это еще раз, потому что фактические стратегии доступа к данным, используемые в вычислениях, могут быть совершенно другими . Но результаты должны быть такими, как если бы этот процесс был выполнен, как описано.
EDIT
В более формальной логической терминологии:
Запрос запрашивает
{СТУДЕНТ | ДЛЯ ВСЕХ КУРСОВ: ЗАПИСАНО (SID, CID)}
в ENROLLED (), SID привязан к ограниченному набору STUDENT, а CID привязан к теме FORALL.
(Возможно, в качестве упражнения проверьте, насколько это почти буквально постановка задачи.)
Отрицанием FORALL, это то же самое, что и
{СТУДЕНТ | КУРС НЕ СУЩЕСТВУЕТ: НЕ ЗАПИСАН (SID, CID)}
И условие NOT ENROLLED (), являющееся истинным, отмечается отсутствием (то есть несуществованием) соответствующей строки SID, CID. Опять же, в качестве упражнения, проверьте, насколько это практически буквально решение SQL.