Вам понадобятся цифры или календарная таблица, чтобы упростить задачу, или мы можем смоделировать один, если диапазон небольшой. Является ли TaskDate простой датой или она также имеет компонент времени?
Основной план атаки:
declare @StartDate datetime
declare @EndDate datetime
/* Set @StartDate and @EndDate to represent the range */
with Digits as (
select 0 as d union all select 1 union all select 2 union all select 3 union all select 4 union all
select 5 union all select 6 union all select 7 union all select 8 union all select 9
), Numbers as (
select (D1.d * 100) + (D2.d * 10) + D3.d as n
from Digits D1,Digits D2,Digits D3
), TaskDates as (
select
t.TaskID,
DATEADD(day,n.n,@StartDate) as TaskDate
from
Tasks t
inner join
Numbers n
on
DATEADD(day,n.n,@StartDate) <= @EndDate
)
select
*
from
TaskDates td1
left join
TasksDone td2
on
td1.TaskID = td2.TaskID and
DATEDIFF(day,td1.TaskDate,td2.TaskDate) = 0
where
td2.TaskID is null
Первые два CTE создают таблицу небольших чисел, третий CTE создает набор идентификаторов задач и дат в требуемом диапазоне. Окончательный выбор сопоставляет тезисы с таблицей TasksDone, а затем отбрасывает те строки, в которых найдено совпадение. Если TasksDone.TaskDate представляет собой обычную дату (без компонента времени), а @StartDate также не имеет компонента времени, то вы можете отказаться от DATEDIFF и просто использовать td1.TaskDate = td2.TaskDate.
Если вам нужен большой диапазон (выше может охватывать ~ 3 года), я бы предложил создать правильную таблицу чисел или календарную таблицу