Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Comment ignorer les intervalles de chevauchement dans la requête suivante pour obtenir le temps de piste précis par jour

Il s'agit d'un problème de "lacunes et d'îlots". J'ai truqué mes propres données de test (puisque vous n'en avez fourni aucune), mais je pense que cela fonctionne. L'intuition clé est que toutes les valeurs dans le même "îlot" (c'est-à-dire un intervalle de temps contigu) auront la même différence par rapport à une colonne row_number(). Si vous voulez en savoir un peu plus, faites une sélection brute à partir de IntervalsByDay cte (par opposition à la sous-requête que j'ai maintenant); cela vous montrera les îles calculées (avec les points de départ et d'arrivée).

edit :je n'avais pas vu que tu avais un violon du premier coup. Ma réponse a été modifiée pour refléter vos données et le résultat souhaité

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