sql >> Base de Datos >  >> RDS >> Sqlserver

Cómo omitir los intervalos de superposición en la siguiente consulta para obtener el tiempo de seguimiento exacto por día

Este es un problema de "brechas e islas". Falsifiqué mis propios datos de prueba (ya que no proporcionaste ninguno), pero creo que funciona. La intuición clave es que todos los valores dentro de la misma "isla" (es decir, intervalo de tiempo contiguo) tendrán la misma diferencia con respecto a una columna número_fila(). Si desea conocerlo un poco, haga una selección sin formato de IntervalsByDay cte (a diferencia de la subconsulta que tengo ahora); esto le mostrará las islas calculadas (con puntos de inicio y fin).

editar:no vi que tenías un violín en la primera vuelta. Mi respuesta ha sido modificada para reflejar sus datos y el resultado deseado

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