Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Para bater as linhas para dias da semana


Isso é bastante complicado. Aqui está uma abordagem usando funções de janela.

Primeiro, use a tabela de datas para enumerar as datas sem fins de semana (você também pode tirar feriados se quiser). Em seguida, expanda os períodos em um dia por linha, usando uma não equijunção.

Você pode então usar um truque para identificar dias sequenciais. Esse truque é gerar um número sequencial para cada id e subtraí-lo do número sequencial das datas. Esta é uma constante para dias sequenciais. A etapa final é simplesmente uma agregação.

A consulta resultante é algo assim:
with d as (
      select d.*, row_number() over (order by date) as seqnum
      from dates d
      where day not in ('Saturday', 'Sunday')
     )
select t.id, min(t.date) as startdate, max(t.date) as enddate, sum(duration)
from (select t.*, ds.seqnum, ds.date,
             (d.seqnum - row_number() over (partition by id order by ds.date) ) as grp
      from table t join
           d ds
           on ds.date between t.startdate and t.enddate
     ) t
group by t.id, grp;

EDITAR:

Veja a seguir a versão neste violino SQL:
with d as (
      select d.*, row_number() over (order by date) as seqnum
      from datetable d
      where day not in ('Saturday', 'Sunday')
     )
select t.id, min(t.date) as startdate, max(t.date) as enddate, sum(duration)
from (select t.*, ds.seqnum, ds.date,
             (ds.seqnum - row_number() over (partition by id order by ds.date) ) as grp
      from (select t.*, 'abc' as id from table1 t) t join
           d ds
           on ds.dateid between t.startdate and t.enddate
     ) t
group by grp;

Acredito que isso esteja funcionando, mas a tabela de datas não contém todas as datas.