There are a lot of ways for querying this but I think
NOT EXISTS
clause is one of the most verbose.
Consider the following example:
SELECT *
FROM Directors d
WHERE NOT EXISTS (SELECT 1
FROM Movies m
WHERE m.director_id = d.id)
The subquery in the NOT EXISTS clause is a correlated subquery. In other words, logically for each row in the Directors table the subquery is run and end the databses checks if the subquery returns a row or not using the id from the directors row.
For more explanations, have a look at
-
Subquery Fundamentals[
^]
-
Correlated Subqueries[
^]
Another way would be to not use a correlated subquery but fetch the director id's before hand. In such case the query could look something like
SELECT *
FROM Directors d
WHERE d.Id NOT IN (SELECT DISTINCT m.director_id
FROM Movies m)
In this example the list of director id's is created first and for each movie the query checks that the id of a director is not in the list. The keyword DISTINCT is used to eliminate duplicates since it's sufficient that each director id is listed only once regardless of how many movies one has.
For more information about DISTINCT see
SELECT Clause (Transact-SQL)[
^]