Dies ist ein "Lücken und Inseln"-Problem. Ich habe meine eigenen Testdaten gefälscht (da Sie keine bereitgestellt haben), aber ich denke, es funktioniert. Die wichtigste Intuition ist, dass alle Werte innerhalb derselben „Insel“ (d. h. zusammenhängendes Zeitintervall) denselben Unterschied zu einer row_number()-Spalte aufweisen. Wenn Sie einen kleinen Einblick wünschen, führen Sie eine Rohauswahl aus IntervalsByDay
durch cte (im Gegensatz zu der Unterabfrage, die ich jetzt habe); dies zeigt Ihnen die berechneten Inseln (mit Start- und Endpunkt).
Bearbeiten:Ich habe nicht gesehen, dass Sie beim ersten Mal eine Geige hatten. Meine Antwort wurde geändert, um Ihre Daten und die gewünschte Ausgabe widerzuspiegeln
with i as (
select datediff(minute, '2013-01-01', StartTime) as s,
datediff(minute, '2013-01-01', EndTime) as e
from #track
), brokenDown as (
select distinct n.Number
from i
join dbadmin.dbo.Numbers as n
on n.Number >= i.s
and n.Number <= i.e
), brokenDownWithID as (
select Number, Number - row_number() over(order by Number) as IslandID,
cast(dateadd(minute, number, '2013-01-01') as date) as d
from brokenDown
), IntervalsByDay as (
select
dateadd(minute, min(number), '2013-01-01') as [IntervalStart],
dateadd(minute, max(number), '2013-01-01') as [IntervalEnd],
d,
max(Number) - min(Number) + 1 as [NumMinutes]
from brokenDownWithID
group by IslandID, d
)
select d, sum(NumMinutes) as NumMinutes
from IntervalsByDay
group by d
order by d