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

Buscar minutos totales ignorando la superposición (Convertir respuesta basada en cursor a CTE)

La siguiente consulta busca los períodos en los datos, según su definición. Primero utiliza subconsultas correlacionadas para determinar si un registro es el comienzo de un período (es decir, no se superpone con períodos de tiempo anteriores). Luego asigna el "inicio del período" como el inicio más reciente que es el comienzo de un período que no se superpone.

La siguiente consulta (no probada) adopta este enfoque:

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 (Segunda Consulta)

Si dos períodos comienzan al mismo tiempo, aún funciona, porque los valores de AvailStart son los mismos. Debido a las subconsultas correlacionadas, es posible que esto no funcione muy bien incluso en conjuntos de datos de tamaño mediano.

Hay otros métodos para abordar esto. Por ejemplo, si tuviera SQL Server 2012, podría usar funciones de suma acumulativa, que ofrecen un método más simple.