Existem várias maneiras de lidar com linhas ausentes, mas todas são sobre ter outro conjunto de dados para combinar com seus resultados atuais.
Isso pode ser derivado de seus resultados, criado por um CTE ou outro processo (como seu exemplo), ou (minha preferência) usando um modelo permanente juntar-se contra.
O modelo no seu caso pode ser apenas uma tabela de datas, como @datesTBL. A diferença é que ele é criado antecipadamente com, por exemplo, 100 anos de datas.
Sua consulta pode ser semelhante ao seu exemplo, mas eu tentaria o seguinte ...
SELECT
dt.tempDate ,
InstructorID, EventStart,
EventEnd, cancelled,
cancelledInstructor,
EventType, DevName,
Room, SimLocation,
ClassLocation, Event,
Duration, TrainingDesc,
Crew, Notes,
LastAmended, InstLastAmended,
ChangeAcknowledged, Type,
OtherType, OtherTypeDesc,
CourseType
FROM
@datesTBL dt
LEFT OUTER JOIN
OpsInstructorEventsView iv
ON iv.EventStart >= dt.tempDate
AND iv.EventStart < dt.tempDate + 1
AND iv.InstructorID = @InstructorID
WHERE
dt.tempDate >= @StartDate
AND dt.tempDate <= @EndDate
ORDER BY
dt.tempDate,
iv.EventStart
Isso coloca o modelo de calendário à ESQUERDA e, portanto, facilita muitas consultas, pois você sabe que o campo de data do calendário é sempre preenchido, é sempre um valor somente de data (sem parte de tempo), está em ordem, é simples de GROUP BY, etc.