Lösung Cursor?

Also nochmal konkret, erste Zeile vom Ergebnis basiert auf:

Fall 1
WERKS = 1010
MATNR = 59025
erste DateID = 20230626
erste 20 Zeilen (sortiert):
1010 20230626 59025 23 11.000
1010 20230703 59025 133 10.000
1010 20230710 59025 124 9.000
1010 20230717 59025 115 9.000
1010 20230724 59025 107 8.000
1010 20230731 59025 99 8.000
1010 20230807 59025 82 17.000
1010 20230814 59025 62 20.000
1010 20230821 59025 63 19.000
1010 20230828 59025 44 19.000
1010 20230904 59025 28 16.000
1010 20230911 59025 16 12.000
1010 20230918 59025 3 13.000
1010 20230925 59025 0 12.000
1010 20231002 59025 0 11.000
1010 20231009 59025 0 4.000
1010 20231016 59025 0 4.000
1010 20231023 59025 0 5.000
1010 20231030 59025 0 5.000
1010 20231106 59025 0 6.000

mein Rechenweg:
23 Total_Menge_FERT_ABC ist der erste Wert. Jetzt willst du wissen, wieviele Wochen du brauchst, um diese 23 durch WA_Menge_FERT "abzutragen". Wenn ich das richtig in Erinnerung habe, dann war WA_Menge_FERT aus dem ersten Datensatz bereits abgezogen*, also 23 ist quasi schon die Fehlmenge in der Woche. Also die WA_Menge_FERT 11 darf nicht nochmal abgezogen werden.
Erste Woche x - 11* = Rest 23
Zweite Woche 23 - 10 = Rest 13
Dritte Woche 13 - 9 = Rest 4
Vierte Woche 4 - 9 = Rest -5
Daher ist der gesuchte Wert in der ersten Zeile bei mir 4 weil es 4 Wochen dauert um 23 Total_Menge_FERT_ABC "abzutragen".

Auf deine 2 als Ergebnis in Zeile 1 komme ich nur wenn ich a) in der ersten Woche 23 - 11 rechne und b) am Ende den Rest nicht beachte bzw. abrunde. Das kann man machen und würde auch in den nachfolgenden Zeilen zu deinen Ergebnissen passen. Bleibt die Frage am Ende immer abrunden oder kaufmänisch runden? Wie hättens denn gern?

PS: Wenn ich schon im ersten Datensatz 23 - 11 rechne und am Ende der Rest irgendwie entfällt (durch Abrundung), kann es sein das ich hier schon negativ werde. Daher hier mal der Code mit 23 - 11 am Anfang und mit Rest am Ende. Der Wert muss also am Ende auf <= 0 fallen, das ergibt aus meiner Sicht auch mehr Sinn. Aber wenn du das noch anders brauchst stelle ich das etwas um.
 
Werbung:
Code:
WITH tabelle(WERKS,DateID,MATNR,Total_Menge_FERT_ABC,WA_Menge_FERT) AS (
SELECT 1010,20230731,59025,99,8.000 UNION ALL SELECT
1010,20230807,59025,82,17.000 UNION ALL SELECT
1010,20230911,59025,16,12.000 UNION ALL SELECT
1010,20240603,59025,0,0.000 UNION ALL SELECT
1010,20240624,59025,0,0.000 UNION ALL SELECT
1044,20230703,59025,61,3.000 UNION ALL SELECT
1044,20230710,59025,58,3.000 UNION ALL SELECT
1044,20230814,59025,48,0.000 UNION ALL SELECT
1044,20230918,59025,43,2.000 UNION ALL SELECT
1044,20231009,59025,38,1.000 UNION ALL SELECT
1044,20231106,59025,33,1.000 UNION ALL SELECT
1044,20240122,59025,31,0.000 UNION ALL SELECT
1044,20240226,59025,31,0.000 UNION ALL SELECT
1044,20240311,59025,31,0.000 UNION ALL SELECT
1044,20240318,59025,31,0.000 UNION ALL SELECT
1044,20240401,59025,31,0.000 UNION ALL SELECT
1044,20240422,59025,31,0.000 UNION ALL SELECT
1044,20240527,59025,31,0.000 UNION ALL SELECT
1044,20240603,59025,31,0.000 UNION ALL SELECT
1044,20240610,59025,31,0.000 UNION ALL SELECT
1010,20230626,94074,1,0.000 UNION ALL SELECT
1010,20230717,94074,1,0.000 UNION ALL SELECT
1010,20230724,94074,1,0.000 UNION ALL SELECT
1010,20230807,94074,1,1.000 UNION ALL SELECT
1010,20230821,94074,0,0.000 UNION ALL SELECT
1010,20231211,94074,0,0.000 UNION ALL SELECT
1010,20240122,94074,0,0.000 UNION ALL SELECT
1010,20240408,94074,0,0.000 UNION ALL SELECT
1010,20240624,94074,0,0.000 UNION ALL SELECT
1010,20230814,59025,62,20.000 UNION ALL SELECT
1010,20231002,59025,0,11.000 UNION ALL SELECT
1010,20240108,59025,0,0.000 UNION ALL SELECT
1010,20240212,59025,0,0.000 UNION ALL SELECT
1010,20240318,59025,0,0.000 UNION ALL SELECT
1010,20240527,59025,0,0.000 UNION ALL SELECT
1010,20240617,59025,0,0.000 UNION ALL SELECT
1044,20230731,59025,48,4.000 UNION ALL SELECT
1044,20230904,59025,46,1.000 UNION ALL SELECT
1044,20231002,59025,39,2.000 UNION ALL SELECT
1044,20231113,59025,32,1.000 UNION ALL SELECT
1044,20231120,59025,32,0.000 UNION ALL SELECT
1044,20231204,59025,32,0.000 UNION ALL SELECT
1044,20240108,59025,31,0.000 UNION ALL SELECT
1044,20240115,59025,31,0.000 UNION ALL SELECT
1044,20240415,59025,31,0.000 UNION ALL SELECT
1044,20240506,59025,31,0.000 UNION ALL SELECT
1010,20231023,94074,0,0.000 UNION ALL SELECT
1010,20231113,94074,0,1.000 UNION ALL SELECT
1010,20231127,94074,0,1.000 UNION ALL SELECT
1010,20231204,94074,0,0.000 UNION ALL SELECT
1010,20240108,94074,0,0.000 UNION ALL SELECT
1010,20240129,94074,0,0.000 UNION ALL SELECT
1010,20240226,94074,0,0.000 UNION ALL SELECT
1010,20240401,94074,0,0.000 UNION ALL SELECT
1010,20240415,94074,0,0.000 UNION ALL SELECT
1010,20230626,59025,23,11.000 UNION ALL SELECT
1010,20230703,59025,133,10.000 UNION ALL SELECT
1010,20230710,59025,124,9.000 UNION ALL SELECT
1010,20230828,59025,44,19.000 UNION ALL SELECT
1010,20230925,59025,0,12.000 UNION ALL SELECT
1010,20231106,59025,0,6.000 UNION ALL SELECT
1010,20231113,59025,0,6.000 UNION ALL SELECT
1010,20231211,59025,0,4.000 UNION ALL SELECT
1010,20231225,59025,0,4.000 UNION ALL SELECT
1010,20240226,59025,0,0.000 UNION ALL SELECT
1010,20240325,59025,0,0.000 UNION ALL SELECT
1010,20240401,59025,0,0.000 UNION ALL SELECT
1010,20240415,59025,0,0.000 UNION ALL SELECT
1010,20240422,59025,0,0.000 UNION ALL SELECT
1044,20230626,59025,39,2.000 UNION ALL SELECT
1044,20230828,59025,47,1.000 UNION ALL SELECT
1044,20231023,59025,35,2.000 UNION ALL SELECT
1044,20231218,59025,32,0.000 UNION ALL SELECT
1044,20240212,59025,31,0.000 UNION ALL SELECT
1044,20240304,59025,31,0.000 UNION ALL SELECT
1010,20230710,94074,1,0.000 UNION ALL SELECT
1010,20230731,94074,1,0.000 UNION ALL SELECT
1010,20230828,94074,0,0.000 UNION ALL SELECT
1010,20231009,94074,1,1.000 UNION ALL SELECT
1010,20231016,94074,1,1.000 UNION ALL SELECT
1010,20240520,94074,0,0.000 UNION ALL SELECT
1010,20240603,94074,0,0.000 UNION ALL SELECT
1010,20230717,59025,115,9.000 UNION ALL SELECT
1010,20230821,59025,63,19.000 UNION ALL SELECT
1010,20230918,59025,3,13.000 UNION ALL SELECT
1010,20231016,59025,0,4.000 UNION ALL SELECT
1010,20231023,59025,0,5.000 UNION ALL SELECT
1010,20231030,59025,0,5.000 UNION ALL SELECT
1010,20231218,59025,0,3.000 UNION ALL SELECT
1010,20240115,59025,0,0.000 UNION ALL SELECT
1010,20240122,59025,0,0.000 UNION ALL SELECT
1010,20240408,59025,0,0.000 UNION ALL SELECT
1044,20230807,59025,48,0.000 UNION ALL SELECT
1044,20230821,59025,48,0.000 UNION ALL SELECT
1044,20230911,59025,45,1.000 UNION ALL SELECT
1044,20230925,59025,41,2.000 UNION ALL SELECT
1044,20231016,59025,37,1.000 UNION ALL SELECT
1044,20231030,59025,34,1.000 UNION ALL SELECT
1044,20231211,59025,32,0.000 UNION ALL SELECT
1044,20240101,59025,31,1.000 UNION ALL SELECT
1044,20240129,59025,31,0.000 UNION ALL SELECT
1010,20230703,94074,1,0.000 UNION ALL SELECT
1010,20230911,94074,0,0.000 UNION ALL SELECT
1010,20230918,94074,3,0.000 UNION ALL SELECT
1010,20230925,94074,0,0.000 UNION ALL SELECT
1010,20231002,94074,0,0.000 UNION ALL SELECT
1010,20231218,94074,0,0.000 UNION ALL SELECT
1010,20231225,94074,0,0.000 UNION ALL SELECT
1010,20240219,94074,0,0.000 UNION ALL SELECT
1010,20240304,94074,0,0.000 UNION ALL SELECT
1010,20240325,94074,0,0.000 UNION ALL SELECT
1010,20240429,94074,0,0.000 UNION ALL SELECT
1010,20231009,59025,0,4.000 UNION ALL SELECT
1010,20231120,59025,0,7.000 UNION ALL SELECT
1010,20231127,59025,0,6.000 UNION ALL SELECT
1010,20240129,59025,0,0.000 UNION ALL SELECT
1010,20240205,59025,0,0.000 UNION ALL SELECT
1010,20240219,59025,0,0.000 UNION ALL SELECT
1010,20240304,59025,0,0.000 UNION ALL SELECT
1010,20240429,59025,0,0.000 UNION ALL SELECT
1010,20240513,59025,0,0.000 UNION ALL SELECT
1044,20230717,59025,55,3.000 UNION ALL SELECT
1044,20231225,59025,32,0.000 UNION ALL SELECT
1044,20240205,59025,31,0.000 UNION ALL SELECT
1044,20240408,59025,31,0.000 UNION ALL SELECT
1010,20231030,94074,0,1.000 UNION ALL SELECT
1010,20231106,94074,0,0.000 UNION ALL SELECT
1010,20240101,94074,0,0.000 UNION ALL SELECT
1010,20240115,94074,0,0.000 UNION ALL SELECT
1010,20240311,94074,0,0.000 UNION ALL SELECT
1010,20240318,94074,0,0.000 UNION ALL SELECT
1010,20240506,94074,0,0.000 UNION ALL SELECT
1010,20240513,94074,0,0.000 UNION ALL SELECT
1010,20240527,94074,0,0.000 UNION ALL SELECT
1010,20240610,94074,0,0.000 UNION ALL SELECT
1010,20240617,94074,0,0.000 UNION ALL SELECT
1010,20230724,59025,107,8.000 UNION ALL SELECT
1010,20230904,59025,28,16.000 UNION ALL SELECT
1010,20231204,59025,0,5.000 UNION ALL SELECT
1010,20240101,59025,0,3.000 UNION ALL SELECT
1010,20240311,59025,0,0.000 UNION ALL SELECT
1010,20240506,59025,0,0.000 UNION ALL SELECT
1010,20240520,59025,0,0.000 UNION ALL SELECT
1010,20240610,59025,0,0.000 UNION ALL SELECT
1044,20230724,59025,52,3.000 UNION ALL SELECT
1044,20231127,59025,32,0.000 UNION ALL SELECT
1044,20240219,59025,31,0.000 UNION ALL SELECT
1044,20240325,59025,31,0.000 UNION ALL SELECT
1044,20240429,59025,31,0.000 UNION ALL SELECT
1044,20240513,59025,31,0.000 UNION ALL SELECT
1044,20240520,59025,31,0.000 UNION ALL SELECT
1044,20240617,59025,31,0.000 UNION ALL SELECT
1044,20240624,59025,31,0.000 UNION ALL SELECT
1010,20230814,94074,0,0.000 UNION ALL SELECT
1010,20230904,94074,0,0.000 UNION ALL SELECT
1010,20231120,94074,0,0.000 UNION ALL SELECT
1010,20240205,94074,0,0.000 UNION ALL SELECT
1010,20240212,94074,0,0.000 UNION ALL SELECT
1010,20240422,94074,0,0.000
), t0 AS (
--t0 dient einzig und allein dazu aus DateID ein brauchbares Datum zu machen
SELECT    WERKS,
        DateID,
        dateadd(day,convert(INT,right(convert(CHAR(8),DateID),2))-1,
        dateadd(month,convert(INT,right(left(convert(CHAR(8),DateID),6),2))-1,
        dateadd(year,convert(INT,left(convert(CHAR(8),DateID),4))-1900,0)
        )) AS [Date],
        MATNR,
        cast(Total_Menge_FERT_ABC AS INT) AS Total_Menge_FERT_ABC,
        cast(WA_Menge_FERT AS INT) AS WA_Menge_FERT
FROM    tabelle
), t1 AS (
--Basis vom CTE
SELECT    DateID,
        [Date],
        Total_Menge_FERT_ABC,
        WERKS,
        MATNR,
        WA_Menge_FERT,
        Total_Menge_FERT_ABC - WA_Menge_FERT AS rest, --*hier war es vorher ohne - WA_Menge_FERT
        1 AS [count]
FROM    t0
UNION ALL
--Rekursion vom CTE
SELECT    t1.DateID,
        t1.[Date],
        t1.Total_Menge_FERT_ABC,
        t1.WERKS,
        t1.MATNR,
        t1.WA_Menge_FERT,
        t1.rest - t0.WA_Menge_FERT AS rest,
        t1.[count] + 1 AS [count]
FROM    t1
INNER JOIN t0
ON        t1.WERKS = t0.WERKS
AND        t1.MATNR = t0.MATNR
AND        dateadd(day,t1.[count] * 7,t1.[Date]) = t0.[Date]
--der max(count) ist später interessant, also beim letzten Datensatz count = gesuchter Wert
WHERE    t1.rest > 0
--bei count = 99 dauert es dann 99 Wochen oder länger, hier wird eine Endlosrekursion verhindert und die Performance kann verbessert werden in dem Härtefälle nicht weiter durchgerechnet werden
AND        t1.[count] + 1 <= 99
), t2 AS (
SELECT    ROW_NUMBER() OVER (PARTITION BY WERKS, MATNR, [Date] ORDER BY [count] DESC) AS zeile,
        DateID,
        [Date],
        Total_Menge_FERT_ABC,
        WERKS,
        MATNR,
        WA_Menge_FERT,
        rest,
        [count]
FROM    t1
)
SELECT    DateID,
        [Date],
        Total_Menge_FERT_ABC,
        WERKS,
        MATNR,
        WA_Menge_FERT,
        rest,
        (CASE WHEN rest <= 0 THEN [count] ELSE NULL END) AS gesuchter_wert
FROM    t2
WHERE    zeile = 1
ORDER BY WERKS, MATNR, [Date], [count]
Die einzige Änderung ist mit --* markiert.
 
@ukulele: Das stimmt auch fast.
Es gibt offensichtlich auch nur zwei kleine Herausforderung.
1. Der Wert WA_Menge_FERT ist aus Total_Menge_FERT_ABC bereits rausgerechnet.
2. Die Reichweite berücksichtigt offensichtlich nicht die 0 Werte bei WA_Menge_FERT. In den beigefügten Beispiel müsste in Zeile 425 eigentlich ein Wert von 6 bzw. 7 nach deiner Darstellung rauskommen. In einem weitere Beispiel müsste statt der 11 eine 53 rauskommen, da nach den 11 Wochen nur '0' Werte bis zum Ende des Betrachtungszeitraums rauskommen.
3. Meinchmal scheint die Berechnung auch erst nicht zu funktionieren (Zeile 1061) um dann zu funktionieren (Zeile 1066). Siehe Beispiel2.
 

Anhänge

  • Beispiel.png
    Beispiel.png
    21,9 KB · Aufrufe: 6
  • Beispiel2.png
    Beispiel2.png
    23 KB · Aufrufe: 6
1. Der Wert WA_Menge_FERT ist aus Total_Menge_FERT_ABC bereits rausgerechnet.
Ja also dann machst du diese Änderung
Code:
        Total_Menge_FERT_ABC - WA_Menge_FERT AS rest, --*hier war es vorher ohne - WA_Menge_FERT
wieder rückgängig
Code:
        Total_Menge_FERT_ABC /*- WA_Menge_FERT*/ AS rest,
und schon wird im ersten Datensatz WA_Menge_FERT wieder nicht mehr abgezogen, nur in den folgenden Wochen. Das muss doch genau das sein, was du suchst. Nur das du in #30 der Meinung bist das in Zeile 1 eine 2 kommen müsste, das ist dann bei mir 4. Wie ich in #31 ausführlich nur für diese eine Zeile dargelegt habe ist 4 dann aus meiner Sicht richtig. Ich weiß wirklich nicht wie ich da auf 2 kommen soll. Wir drehen uns bei der Sache auch im Kreis, zumal deine Ergebnisse alle um 2 abweichen. Was ist denn jetzt das richtige Ergebnis?
2. Die Reichweite berücksichtigt offensichtlich nicht die 0 Werte bei WA_Menge_FERT. In den beigefügten Beispiel müsste in Zeile 425 eigentlich ein Wert von 6 bzw. 7 nach deiner Darstellung rauskommen.
Wieder neuer Fall, das hilft nicht so richtig wenn der Rest schon nicht passt oder vermeintlich nicht passt. Deine neuen Testdaten:
Code:
WITH tabelle(WERKS,DateID,MATNR,Total_Menge_FERT_ABC,WA_Menge_FERT) AS (
SELECT 1010,20231002,2635,3,1 UNION ALL
SELECT 1010,20231009,2635,2,0 UNION ALL
SELECT 1010,20231016,2635,2,0 UNION ALL
SELECT 1010,20231023,2635,2,0 UNION ALL
SELECT 1010,20231030,2635,2,2 UNION ALL
SELECT 1010,20231106,2635,0,0 UNION ALL
SELECT 1010,20231113,2635,0,0 UNION ALL
SELECT 1010,20231120,2635,0,1
)
Mein Ergebnis
DateID Date Total_Menge_FERT_ABC WERKS MATNR WA_Menge_FERT rest gesuchter_wert
----------- ----------------------- -------------------- ----------- ----------- ------------- ----------- --------------
20231002 2023-10-02 00:00:00.000 3 1010 2635 1 0 8
20231009 2023-10-09 00:00:00.000 2 1010 2635 0 0 4
20231016 2023-10-16 00:00:00.000 2 1010 2635 0 0 3
20231023 2023-10-23 00:00:00.000 2 1010 2635 0 0 2
20231030 2023-10-30 00:00:00.000 2 1010 2635 2 1 NULL
20231106 2023-11-06 00:00:00.000 0 1010 2635 0 0 1
20231113 2023-11-13 00:00:00.000 0 1010 2635 0 0 1
20231120 2023-11-20 00:00:00.000 0 1010 2635 1 0 1

2023-10-02
Total_Menge_FERT_ABC = 3
WA_Menge_FERT = 1 (unberücksichtigt, daher 0)
verbleibend = 3
Zähler = 1

2023-10-09
WA_Menge_FERT = 0
verbleibend = 3
Zähler = 2

2023-10-16
WA_Menge_FERT = 0
verbleibend = 3
Zähler = 3

2023-10-23
WA_Menge_FERT = 0
verbleibend = 3
Zähler = 4

2023-10-30
WA_Menge_FERT = 2
verbleibend = 3 - 2 = 1
Zähler = 5

2023-11-06
WA_Menge_FERT = 0
verbleibend = 1
Zähler = 6

2023-11-13
WA_Menge_FERT = 0
verbleibend = 1
Zähler = 7

2023-11-20
WA_Menge_FERT = 1
verbleibend = 1 - 1 = 0
Zähler = 8 = Ergebnis 8

Nach meiner manuellen Rechnung müsste 8 raus kommen wenn WA_Menge_FERT vom 2023-10-02 unberücksichtigt bleibt. Bitte dazu unbedingt eine klare Aussage ob das jetzt richtig ist.
(PS: Wenn ich WA_Menge_FERT vom 2023-10-02 berücksichtige dann ist der gesuchte Wert 5. Auch das kann ich manuell nach rechnen und komme auf das selbe Ergebnis.)

Ich kann überhaupt keinen Fehler finden und ich kann deine Aussage, das 0 Werte "offensichtlich nicht berücksichtigt werden", gar nicht nachvollziehen. Welche 0 Werte denn jetzt? Die Testdaten von Screenshot 1 einmal durch gerechnet passt bei mir alles. Oder ich verstehe deine Aussage nicht oder was du als Ergebnis erwartest.

...In einem weitere Beispiel müsste statt der 11 eine 53 rauskommen, da nach den 11 Wochen nur '0' Werte bis zum Ende des Betrachtungszeitraums rauskommen.
Das rechne ich jetzt nicht weiter nach. Poste mir bitte die Testdaten als kleine Tabelle wie in dem Code oben mit WITH oder auf SQL Fiddle. Rechne es selbst mit meinem Code nach, sag was du raus hast und sag mir, was deiner Meinung nach raus kommen müsste und vor allem warum.
3. Meinchmal scheint die Berechnung auch erst nicht zu funktionieren (Zeile 1061) um dann zu funktionieren (Zeile 1066). Siehe Beispiel2.
Guck dir bitte jeden Fall genau an, es ist die selbe Berechnung, immer. Rechne manuell nach was raus kommen müsste.
 
Werbung:
Hallo IchHH,

eine interessante Thematik, die du hier gepostet hast. Da musste ich mich jetzt auch einfach mal mit beschäftigen.

@ukulele hat ja schon den korrekten Ansatz mit der rekursiven CTE geliefert, die ja letztendlich nur eine Wert-Kumulation durchführt.

Ab dem SQL Server 2016 kann man diese Kumulation auch direkt mit einer Fensterfunktion vornehmen.
Was in jedem Fall sein muss ist ein Zwischenergebnis. Ich habe ein Beispiel entworfen, in dem ich dieses Zwischenergebnis zunächst in eine temporäre Tabelle geschrieben habe. Die eigentliche Ergebnis-Abfrage basiert darauf.

Ich bin mir nicht sicher, ob ich direkt das korrekte Ergebnis erzielt habe, es kamen ja dann doch noch ein paar zusätzliche Definitions-Angaben hintendrauf und bei der Behandlung des "wann ist was zu berücksichtigen" (Werte größer o. kleiner, Datum berücksichtigen etc.) bin ich mir nicht sicher, ob ich das komplett geblickt habe. Das Ergebnis basiert auf der Tabelle, die du auf der 2. Seite dieses Threads gepostet hast.

Hier einmal meine Lösung:

SQL:
IF OBJECT_ID('TempDB..#a') IS NOT NULL DROP TABLE #a

SELECT TOP 100 PERCENT
w.ID,
w.WERKS,
w.MATNR,
w.DateID as AnfangDatum,
YEAR(w.DateID) * 100 + DATEPART(ISO_WEEK, w.DateID) as YearKW,
w.Total_Menge_FERT_ABC,
w.WA_Menge_FERT as WA_Menge_FERT_orig,
f.DateID as FertigDatum,
f.WA_Menge_FERT,

SUM(f.WA_Menge_FERT) OVER (PARTITION BY w.WERKS, w.MATNR, w.DateID ORDER BY f.WERKS, f.MATNR,f.DateID ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as WA_Menge_FERT_kum,

(CASE WHEN SUM(f.WA_Menge_FERT) OVER (PARTITION BY w.WERKS, w.MATNR, w.DateID ORDER BY f.WERKS, f.MATNR,f.DateID ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) <= w.Total_Menge_FERT_ABC THEN 0 ELSE 1 END) as Erreicht

,COUNT(*) OVER (PARTITION BY w.WERKS, w.MATNR, w.DateID ORDER BY f.WERKS, f.MATNR,f.DateID ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as WerksMatNrRowNr

-- in temporäre Tabelle, um ein Zwischenergebnis abfragen zu können
-- kann auch direkt als Sub-Select in die untere Abfrage eingebaut werden oder vorab als CTE
INTO #a

FROM [dbo].[wrkdata] w

LEFT OUTER JOIN [dbo].[wrkdata] f
    ON f.WERKS = w.WERKS
    AND f.MATNR = w.MATNR
    AND f.DateID >= w.DateID

    
ORDER BY
w.WERKS,
w.MATNR,
w.DateID,
f.DateID

---- Detail-Zwischenergebnis
--SELECT * FROM #a WHERE


-- Ergebnis-Tabelle mit berechneter KW-Reichweite
SELECT
w.WERKS,
w.MATNR,
CONVERT(varchar(50), w.AnfangDatum, 112) as DateID,
w.YearKW,
w.Total_Menge_FERT_ABC,
MAX(w.WA_Menge_FERT_orig) as WA_Menge_FERT,

-- bei nicht zu ermittelnder Reichweite den Maximalen Wert setzen
(CASE WHEN SUM(CASE WHEN w.Erreicht = 0 THEN w.WA_Menge_FERT ELSE 0 END) = 0 THEN 53
 ELSE MAX(CASE WHEN w.Erreicht = 0 THEN WerksMatNrRowNr ELSE 0 END) END) as KWReichweite,

-- Angabe der KW im entsprechendem Jahr, ausgegangen von vorheriger Berechnung der KW-Reichweite
(CASE WHEN SUM(CASE WHEN w.Erreicht = 0 THEN w.WA_Menge_FERT ELSE 0 END) = 0 OR MAX(CASE WHEN w.Erreicht = 1 THEN YEAR(w.FertigDatum) * 100 + DATEPART(ISO_WEEK, w.FertigDatum) ELSE 0 END) = 0
        THEN (SELECT MAX(YEAR(x.AnfangDatum) * 100 + DATEPART(ISO_WEEK, x.AnfangDatum)) FROM #a x WHERE x.WERKS = w.WERKS AND x.MATNR = w.MATNR)
ELSE MAX(CASE WHEN w.Erreicht = 0 THEN YEAR(w.FertigDatum) * 100 + DATEPART(ISO_WEEK, w.FertigDatum) ELSE 0 END) END) as BisYearKW

--,SUM(CASE WHEN Erreicht = 0 THEN w.WA_Menge_FERT ELSE 0 END) as WA_Menge_FERT_Summe

FROM #a w


GROUP BY
w.WERKS,
w.MATNR,
w.AnfangDatum,
w.YearKW,
w.Total_Menge_FERT_ABC

ORDER BY
w.WERKS,
w.MATNR,
w.YearKW


Viele Grüße.
Tommi
 
Zurück
Oben