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

Per club le file per i giorni della settimana

Questo è piuttosto complicato. Ecco un approccio che utilizza le funzioni della finestra.

Per prima cosa, usa la tabella delle date per enumerare le date senza fine settimana (puoi anche prendere le ferie se lo desideri). Quindi, espandi i periodi in un giorno per riga, utilizzando un non equijoin.

È quindi possibile utilizzare un trucco per identificare i giorni sequenziali. Questo trucco consiste nel generare un numero sequenziale per ogni ID e sottrarlo dal numero sequenziale per le date. Questa è una costante per i giorni sequenziali. Il passaggio finale è semplicemente un'aggregazione.

La query risultante è qualcosa del genere:

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;

MODIFICA:

Quella che segue è la versione su questo SQL Violino:

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;

Credo che funzioni, ma la tabella delle date non contiene tutte le date.