sql >> Database teknologi >  >> RDS >> Sqlserver

Find det samlede antal minutter, der ignorerer overlap (Konverter markørbaseret svar til CTE)

Følgende forespørgsel finder perioderne i dataene i henhold til din definition. Den bruger først korrelerede underforespørgsler til at bestemme, om en post er starten på en periode (dvs. ingen overlapning med tidligere tidsperioder). Den tildeler derefter "periodeStart" som den seneste start, der er begyndelsen på en ikke-overlappende periode.

Følgende (ikke-testede) forespørgsel tager denne tilgang:

with TimeWithOverlap as (
     select t.*,
            (case when exists (select * from dbo.Available tbefore where t.availStart > tbefore.availStart and tbefore.availEnd >= t.availStart)
                  then 0
                  else 1
             end) as IsPeriodStart
     from dbo.Available t 
    ),
    TimeWithPeriodStart as (
     select two.*,
            (select MAX(two1.AvailStart) from TimeWithOverlap two1 where IsPeriodStart = 1 and two1.AvailStart <= two.AvailStart
            ) as periodStart
     from TimeWithOverlap two
    )
select periodStart, MAX(AvailEnd) as periodEnd
from TimeWithPeriodStart twps
group by periodStart;

http://sqlfiddle.com/#!6/3483c/20 (Anden forespørgsel)

Hvis to perioder begge starter på samme tid, så virker det stadig, fordi AvailStart-værdierne er de samme. På grund af de korrelerede underforespørgsler fungerer dette muligvis ikke særlig godt på selv mellemstore datasæt.

Der er andre metoder til at gribe dette an. Hvis du for eksempel havde SQL Server 2012, ville du være i stand til at bruge kumulative sumfunktioner, som tilbyder en enklere metode.



  1. MySQL-forespørgsel for at søge i et felt med JSON-streng

  2. importere massedata til MySQL

  3. IF condition i vælg min sql-forespørgsel

  4. MySQL - Sådan normaliseres kolonne, der indeholder skilletegn-separerede ID'er