--Rohdaten
;WITH data(Artikel,Bezeichnung,Fertigungsartikel,Produktionsauftrag,Auftragsstatus,Gesamtmenge,Starttermin,Liefertermin) AS(
SELECT '600001','Bezeichnung1','110049','P100011','Aktiv',400,cast('2018-06-28' AS DATE),cast('2018-07-01' AS DATE) UNION ALL
SELECT '600068','Bezeichnung2','110050','P100012','Aktiv',600,'2018-06-27','2018-07-10' UNION ALL
SELECT '600045','Bezeichnung3','110055','P100013','Aktiv',1500,'2018-07-14','2018-08-02' UNION ALL
SELECT '600065','Bezeichnung4','110060','P100014','Aktiv',100,'2018-07-05','2018-07-06'
),
--Kalendertabelle
kalender (Artikel,Bezeichnung,Fertigungsartikel,Produktionsauftrag,Auftragsstatus,Gesamtmenge,Starttermin,Liefertermin) AS (
SELECT
data.Artikel,
data.Bezeichnung,
data.Fertigungsartikel,
data.Produktionsauftrag,
data.Auftragsstatus,
data.Gesamtmenge,
data.Starttermin,
data.Liefertermin
FROM
data
UNION ALL
SELECT
kalender.Artikel,
kalender.Bezeichnung,
kalender.Fertigungsartikel,
kalender.Produktionsauftrag,
kalender.Auftragsstatus,
kalender.Gesamtmenge,
DATEADD(day,1,kalender.Starttermin),
kalender.Liefertermin
FROM
kalender
WHERE
kalender.Starttermin < Liefertermin
),
--Kalenderwochen ermitteln vom Zeitraum zwischen Starttermin und Liefertermin
Zwischenzeitraum(Artikel, Produktionsauftrag,Starttermin, KW) AS (
SELECT
kalender.Artikel,
kalender.Produktionsauftrag,
CONVERT(date,DATEADD(WEEK,0,DATEADD(DAY,1-DATEPART(DW,kalender.Starttermin),DATEDIFF(DAY,0,kalender.Starttermin)))),
DATEPART(WEEK,kalender.Starttermin)
FROM
kalender
WHERE
DATEPART(WEEKDAY,kalender.Starttermin) NOT IN (6,7)
GROUP BY
kalender.Artikel,kalender.Produktionsauftrag,DATEADD(WEEK,0,DATEADD(DAY,1-DATEPART(WEEKDAY,kalender.Starttermin),DATEDIFF(DAY,0,kalender.Starttermin))),DATEPART(WEEK,kalender.Starttermin)
)
--QUERY
SELECT
Zwischenzeitraum.Artikel,
data.Bezeichnung,
data.Fertigungsartikel,
Zwischenzeitraum.Produktionsauftrag,
data.Auftragsstatus,
data.Gesamtmenge,
data.Starttermin,
data.Liefertermin,
--Arbeitstage vom Gesamtzeitraum ermitteln
SUM(DATEDIFF(DAY,CASE WHEN DATEPART(WEEK,data.Starttermin) = Zwischenzeitraum.KW THEN data.Starttermin ELSE Zwischenzeitraum.Starttermin END,CASE WHEN DATEPART(WEEK,data.Liefertermin) = Zwischenzeitraum.KW THEN (CASE WHEN DATEPART(WEEKDAY,data.Liefertermin) > 5 THEN DATEADD(DAY,(DATEPART(WEEKDAY,data.Liefertermin)*-1+5),data.Liefertermin) ELSE data.Liefertermin END) ELSE DATEADD(DAY,4,Zwischenzeitraum.Starttermin) END) + 1) OVER (PARTITION BY Zwischenzeitraum.Produktionsauftrag,Zwischenzeitraum.Artikel) AS AT_Gesamt,
Zwischenzeitraum.KW,
--START_Teilzeitraum ermitteln
CASE
WHEN DATEPART(WEEK,data.Starttermin) = Zwischenzeitraum.KW
THEN data.Starttermin
ELSE Zwischenzeitraum.Starttermin
END AS START_Teilzeitraum,
--ENDE_Teilzeitraum ermitteln
CASE
WHEN DATEPART(WEEK,data.Liefertermin) = Zwischenzeitraum.KW
THEN
(CASE
WHEN DATEPART(WEEKDAY,data.Liefertermin) > 5
THEN DATEADD(DAY,(DATEPART(WEEKDAY,data.Liefertermin)*-1+5),data.Liefertermin)
ELSE data.Liefertermin
END)
ELSE DATEADD(DAY,4,Zwischenzeitraum.Starttermin)
END AS ENDE_Teilzeitraum,
--Arbeitstage vom Teilzeitraum ermitteln
DATEDIFF(DAY,CASE WHEN DATEPART(WEEK,data.Starttermin) = Zwischenzeitraum.KW THEN data.Starttermin ELSE Zwischenzeitraum.Starttermin END,CASE WHEN DATEPART(WEEK,data.Liefertermin) = Zwischenzeitraum.KW THEN (CASE WHEN DATEPART(WEEKDAY,data.Liefertermin) > 5 THEN DATEADD(DAY,(DATEPART(WEEKDAY,data.Liefertermin)*-1+5),data.Liefertermin) ELSE data.Liefertermin END) ELSE DATEADD(DAY,4,Zwischenzeitraum.Starttermin) END) + 1 AS AT_Teilzeitraum,
--Menge berechnen (Gesamtmenge / AT_Gesamt * AT_Teilzeitraum)
(data.Gesamtmenge / (SUM(DATEDIFF(DAY,CASE WHEN DATEPART(WEEK,data.Starttermin) = Zwischenzeitraum.KW THEN data.Starttermin ELSE Zwischenzeitraum.Starttermin END,CASE WHEN DATEPART(WEEK,data.Liefertermin) = Zwischenzeitraum.KW THEN (CASE WHEN DATEPART(WEEKDAY,data.Liefertermin) > 5 THEN DATEADD(DAY,(DATEPART(WEEKDAY,data.Liefertermin)*-1+5),data.Liefertermin) ELSE data.Liefertermin END) ELSE DATEADD(DAY,4,Zwischenzeitraum.Starttermin) END) + 1) OVER (PARTITION BY Zwischenzeitraum.Produktionsauftrag,Zwischenzeitraum.Artikel))) * (DATEDIFF(DAY,CASE WHEN DATEPART(WEEK,data.Starttermin) = Zwischenzeitraum.KW THEN data.Starttermin ELSE Zwischenzeitraum.Starttermin END,CASE WHEN DATEPART(WEEK,data.Liefertermin) = Zwischenzeitraum.KW THEN (CASE WHEN DATEPART(WEEKDAY,data.Liefertermin) > 5 THEN DATEADD(DAY,(DATEPART(WEEKDAY,data.Liefertermin)*-1+5),data.Liefertermin) ELSE data.Liefertermin END) ELSE DATEADD(DAY,4,Zwischenzeitraum.Starttermin) END) + 1) AS Berechnete_Menge
FROM
Zwischenzeitraum
INNER JOIN data ON (Zwischenzeitraum.Produktionsauftrag = data.Produktionsauftrag AND Zwischenzeitraum.Artikel = data.Artikel)