sql >> Databasteknik >  >> RDS >> Sqlserver

Hitta totalt antal minuter och ignorera överlappning (konvertera markörbaserat svar till CTE)

Följande fråga hittar perioderna i data, enligt din definition. Den använder först korrelerade underfrågor för att avgöra om en post är början på en period (det vill säga ingen överlappning med tidigare tidsperioder). Den tilldelar sedan "periodStart" som den senaste starten som är början på en icke-överlappande period.

Följande (otestad) fråga använder detta tillvägagångssätt:

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 (Andra frågan)

Om två perioder båda startar samtidigt, så fungerar det fortfarande, eftersom AvailStart-värdena är desamma. På grund av de korrelerade underfrågorna kanske detta inte fungerar särskilt bra på ens medelstora datamängder.

Det finns andra metoder för att närma sig detta. Om du till exempel hade SQL Server 2012 skulle du kunna använda kumulativa summafunktioner, som erbjuder en enklare metod.



  1. MySQL InnoDB låser endast de berörda raderna?

  2. Behörigheter för att skapa en trigger i mysql

  3. Icke-trivial sammanslagning av två tabeller

  4. Grekisk text visas inte korrekt