Suponha que haja uma coluna id exclusiva e, para tornar as coisas interessantes, ela não rastreia os aumentos na coluna timestamp. Assuma também que não há carimbos de data e hora iguais.
select pt.* from
(Select max(ptime) as prevtime,min(ntime) as nextime from
((Select timestamp as ptime) as prev,
(Select timestamp as ntime) as next
where prev.ptime < next.ntime and prev.id<>next.id) as s1 group by ptime, ntime) as pn
inner join
t as pt on pn.prevtime=pt.timestamp inner join
t as nt on pn.nexttime=nt.timestamp
where pt.ncol!=nt.ncol;
Explicação:s1 fornece pares de tempos que são anteriores e posteriores um ao outro. pn os agrupa para obter uma lista de todos os pares de tempos adjacentes. pt fornece o restante das colunas da vez anterior em pn e nt fornece o restante das colunas da próxima vez. Quando a coluna que chamei de ncol muda de valor, a linha anterior é cuspida no conjunto de resultados. Se houver vários valores não nulos e só for interessante encontrar as opções entre nulo e não nulo, altere pt.ncol!=nt.ncol para isnull(pt.ncol)!=isnull(nt.ncol).