Denne forespørgsel ved hjælp af analytisk lead()
gør jobbet. Kolonne note
viser, om rækken kommer fra dine data, eller om den mangler mellemrum:
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)
Til at begynde med er data ikke pivoteret bare for at have alle datoer i én kolonne, det er nemmere for yderligere analyser. Union fjerner duplikerede værdier. Kolonne dir
informerer om dette er from
eller to
dato. Så lead
logik anvendes, afhængigt af typen af denne retning. Jeg tror det kan forenkles noget :)