Invece di confrontare la data di annullamento nella riga precedente, è necessario confrontare l'ultima data di annullamento in tutte le righe precedenti. L'SQL standard ha un'opzione IGNORE NULLS per raggiungere questo obiettivo, ma MySQL non la supporta. Fortunatamente nel tuo caso può essere riscritto usando un Cumulative Max:
select t.*,
datediff(start, prev_cancelled) as num_days_since_cancel
from (select dt.*,
max(cancelled) over -- latest date per id
(partition by id
order by start
rows between unbounded preceding and 1 preceding) as prev_cancelled
from dt
) t
-- remove negative duration
where datediff(start, prev_cancelled) >= 0;
Vedi violino