Хитрость заключается не в том, чтобы отфильтровывать те самые строки, которые вам нужны, когда вы пытаетесь выбрать те, которые не соответствуют. Возможно, что-то вроде:
SELECT DISTINCT profs.namn, profs.tel
FROM (SELECT DISTINCT namn, tel FROM Courses) as profs
LEFT JOIN Courses c ON profs.namn = c.namn AND c.nickname = 'AS'
WHERE c.namn IS NULL
Подзапрос (profs) дает вам список каждого профессора и их телефонный номер без дубликатов (обратите внимание, если они перечислены с более чем одним телефонным номером, вы ' Я получу их отдельно с каждым номером телефона). Затем это LEFT СОЕДИНЯЕТСЯ со всей таблицей, чтобы связать каждого преподавателя с его курсами, но предложение ON также ограничивает эти совпадения тем курсом, который вы исключите sh (вы также можете использовать IN и список из нескольких значений), поэтому только те профессора, которые не преподают класс 'AS' (или любой из списка IN, если вы его используете), не смогут соответствовать предложению ON и приведут к значениям NULL для таблицы c в результате внешнего соединения .
Предложение WHERE применяется после вычисления внешнего соединения и выбирает только те, которые имеют значения NULL, другими словами, те, которые не обучают указанному классу (классам). DISTINCT во внешнем SELECT может не потребоваться. Размещение условий в выражениях WHERE или определенных ON включено при использовании внешних объединений.
Могут быть и другие способы сделать это; Я не уверен, что это лучше, но я думаю, что это сработает. Вероятно, есть способ сделать это с помощью Count, GROUP BY и HAVING, но я думаю, что это в конечном итоге примерно такой же сложности (с очень похожей структурой) и не так гибко.