use [test1_AlplaPROD2.0_Read] DECLARE @start_date date = '[startDate]'; --'2025-01-01' DECLARE @end_date date = '[endDate]'; --'2025-08-09' DECLARE @tz sysname = 'Eastern Standard Time'; -- usday1; use 'Central Standard Time' for usksc1 DECLARE @shiftSeconds int = 7*3600; -- 07:00 production-day anchor --TODO: add in the proper time zone based on the env, get correcr shift time as well ;WITH src AS ( SELECT pl.RunningNumber, pl.ArticleHumanReadableId, pl.ArticleAlias, pl.ArticleDescription, pl.MachineLocation, pl.MachineDescription, pl.ProductionLotState, pl.ProductionInterrupt, pl.PlanQuantityPieces, pl.PlanQuantityLoadingUnit, CAST(pl.ProdStart AT TIME ZONE @tz AS datetime2(0)) AS StartLocal, CAST(pl.PlanEnd AT TIME ZONE @tz AS datetime2(0)) AS EndLocal FROM productionScheduling.ProductionLot AS pl WHERE pl.PlanEnd > pl.ProdStart and pl.publishState = 1 and pl.ArticleHumanReadableId IN ([articles]) -- <-- article filter (was IdArtikelvarianten) --AND pl.RunningNumber = 28094 -- <-- lot filter (was IdProdPlanung); comment out for all ), calc AS ( SELECT *, DATEADD(SECOND, @shiftSeconds, CAST(CASE WHEN DATEDIFF(SECOND, CAST(StartLocal AS date), StartLocal) >= @shiftSeconds THEN CAST(StartLocal AS date) ELSE DATEADD(DAY,-1, CAST(StartLocal AS date)) END AS datetime2(0))) AS FirstBoundary FROM src ), days AS ( -- one row per production day the lot touches SELECT RunningNumber, ArticleHumanReadableId, ArticleAlias, ArticleDescription, MachineLocation, MachineDescription, ProductionLotState, PlanQuantityPieces, PlanQuantityLoadingUnit, StartLocal, EndLocal, FirstBoundary AS DayStart FROM calc UNION ALL SELECT RunningNumber, ArticleHumanReadableId, ArticleAlias, ArticleDescription, MachineLocation, MachineDescription, ProductionLotState, PlanQuantityPieces, PlanQuantityLoadingUnit, StartLocal, EndLocal, DATEADD(DAY,1,DayStart) FROM days WHERE DATEADD(DAY,1,DayStart) < EndLocal ), seg AS ( -- working seconds inside each production day SELECT *, DATEDIFF(SECOND, CASE WHEN StartLocal > DayStart THEN StartLocal ELSE DayStart END, CASE WHEN EndLocal < DATEADD(DAY,1,DayStart) THEN EndLocal ELSE DATEADD(DAY,1,DayStart) END ) AS SegSec FROM days ), cum AS ( -- cumulative seconds for telescoping round SELECT *, SUM(SegSec) OVER (PARTITION BY RunningNumber ORDER BY DayStart ROWS UNBOUNDED PRECEDING) AS CumEnd, SUM(SegSec) OVER (PARTITION BY RunningNumber ORDER BY DayStart ROWS UNBOUNDED PRECEDING) - SegSec AS CumStart, SUM(SegSec) OVER (PARTITION BY RunningNumber) AS DenomSec FROM seg ) SELECT ArticleHumanReadableId AS Article, ArticleAlias AS Description, MachineLocation AS MachineId, MachineDescription AS MachineName, RunningNumber AS LotNumber, FORMAT(DayStart, 'MM/dd/yyyy') AS ProductionDay, PlanQuantityPieces AS TotalPlanned, ROUND(PlanQuantityPieces * 1.0 * CumEnd / DenomSec, 0) - ROUND(PlanQuantityPieces * 1.0 * CumStart / DenomSec, 0) AS QTYPerDay, ROUND(PlanQuantityLoadingUnit * CumEnd / DenomSec, 2) - ROUND(PlanQuantityLoadingUnit * CumStart / DenomSec, 2) AS PalDay, ProductionLotState AS finished FROM cum WHERE CAST(DayStart AS date) BETWEEN @start_date AND @end_date -- filter AFTER cumulative calc ORDER BY RunningNumber, DayStart DESC OPTION (MAXRECURSION 366);