Esta consulta, utilizando analítica lead()
hace el trabajo. Columna note
muestra si la fila proviene de sus datos o si falta un espacio:
select id, d1, d2, case dir when 3 then 'GAP' end note
from (
select id,
case when dir = 2
and lead(dir) over (partition by id order by dt) = 1
and lead(dt) over (partition by id order by dt) <> dt + 1
then dt + 1
else dt
end d1,
case when dir = 2
and lead(dir) over (partition by id order by dt) = 1
and lead(dt) over (partition by id order by dt) <> dt + 1
then 3
else dir
end dir,
case when lead(dir) over (partition by id order by dt) = 1
then lead(dt) over (partition by id order by dt) - 1
else lead(dt) over (partition by id order by dt)
end d2
from (
select * from a unpivot (dt for dir in (validfrom as 1, validto as 2)) union
select * from b unpivot (dt for dir in (validfrom as 1, validto as 2)) ) )
where dir in (1, 3)
Al principio, los datos no están pivotados solo para tener todas las fechas en una columna, es más fácil para análisis posteriores. Union elimina los valores duplicados. Columna dir
informa si esto es from
o to
fecha. Entonces lead
Se aplica la lógica, dependiendo del tipo de esta dirección. Creo que se puede simplificar un poco :)