前の行のキャンセル日と比較する代わりに、前のすべての行の最新のキャンセル日と比較する必要があります。標準SQLにはこれを実現するためのIGNORENULLSオプションがありますが、MySQLはそれをサポートしていません。幸いなことに、あなたの場合、累積最大値を使用して書き直すことができます:
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;
フィドル を参照してください。