Although it sounds like a simple case, there is an additional complication that is that the day of the launch must be set to the previous day when the day crosses the day and the point was struck the day after the start of the turn. This is case 744 in the example posted by the author, at which beat date / time:
2016-06-25 00:05:17.852
changes to the previous day:
2016-06-24
Since shifts begin at full time (always at 0 minutes), a simple way is to turn the shift table by time slot:
inatableofshiftsperhour,startingat0handgoinguntil11h:
Onewaytogetthehourlyshifttableisasinthefollowingcode.
--código#1declare@tbHoratable(Horaint);INSERTinto@tbHoravalues(0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16),(17),(18),(19),(20),(21),(22),(23);--transformaatabeladeturnodefaixahoráriaparahorawithcteTurnoFHas(SELECTcodigo,inicio,dateadd(minute,duracao,inicio)asfimfromtbTurno),cteTurnoHas(SELECTT.codigo,H.HorafromcteTurnoFHasTcrossjoin@tbHoraasHwhere1=casewhendatepart(day,T.inicio)=datepart(day,T.fim)thencasewhenH.Hora>=datepart(hour,T.inicio)andH.Hora<datepart(hour,T.fim)then1else0endelsecasewhenH.Hora>=datepart(hour,T.inicio)orH.Hora<datepart(hour,T.fim)then1else0endend)...
Andtodisplaythepostingswiththeshiftwouldbesomethinglike
--código#2...SELECTL.serie,cast(L.horaasdate)asdia,TH.codigofromtbLançamentoasLinnerjoincteTurnoHasTHonTH.Hora=datepart(hour,L.hora)orderbyL.serie;
However,thereisanadditionalcomplication,whichisthatthelaunchdaymustbesettothepreviousdaywhentheshiftcrossesthedayandthepointwasstruckthedayafterthestartoftheturn.Thisiscase744,intheexamplepostedbytheauthor.
Tohandlethedaysetting,theCTEcteTurnoHhasbeenexpanded,containingacolumnindicatingwhichtimesthedateneedstobeadjusted.Attheendthecodelookslikethis:
--código#3v2setnocounton;--IFObject_ID('tempDB..#TurnoH','U')isnotnullDROPTABLE#TurnoH;CREATETABLE#TurnoH(Horaintprimarykey,codigochar(3),AjusteDiaint);--declare@tbHoratable(Horaint);INSERTinto@tbHoravalues(0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16),(17),(18),(19),(20),(21),(22),(23);--transformaatabeladeturnodefaixahoráriaparahorawithcteTurnoFHas(SELECTcodigo,inicio,dateadd(minute,duracao,inicio)asfimfromtbTurno),cteTurnoHas(SELECTH.Hora,T.codigo,casewhendatepart(day,T.inicio)=datepart(day,T.fim)then0elsecasewhendatepart(hour,T.inicio)<=H.Horathen0else-1endendasAjusteDiafromcteTurnoFHasTcrossjoin@tbHoraasHwhere1=casewhendatepart(day,T.inicio)=datepart(day,T.fim)thencasewhenH.Hora>=datepart(hour,T.inicio)andH.Hora<datepart(hour,T.fim)then1else0endelsecasewhenH.Hora>=datepart(hour,T.inicio)orH.Hora<datepart(hour,T.fim)then1else0endend)INSERTinto#TurnoH(Hora,codigo,AjusteDia)SELECTHora,codigo,AjusteDiafromcteTurnoH;--SELECTL.serie,L.horaasbatida,cast(dateadd(day,TH.AjusteDia,L.hora)asdate)asdia,TH.codigofromtbLançamentoasLinnerjoin#TurnoHasTHonTH.Hora=datepart(hour,L.hora);
Andthefinalresultis
If there is the possibility of a shift starting in fractional time, code # 3 needs to be changed.
There is probably a more efficient solution, but it was the first one that came to mind this morning.