• There is always more than one way to skin a cat. My preference is to optimize simplicity and maintainability. Each part can be tested individually and there are no WHERE clauses.

    SELECT -- get all employees and required courses

    e.EmployeeId,

    e.FirstName,

    e.LastName,

    c.CourseId,

    c.CourseName

    FROM

    #Employee e

    CROSS JOIN

    #Course c

    EXCEPT

    SELECT -- remove completed employee courses

    e.EmployeeId,

    e.FirstName,

    e.LastName,

    c.CourseId,

    c.CourseName

    FROM

    #Employee e

    JOIN

    #CourseCompleted cc ON cc.EmployeeId = e.EmployeeId

    JOIN

    #Course c on cc.CourseId = c.CourseId

    ORDER BY

    e.EmployeeId

    ;