While-Schleife um Wochenende & Feiertage auszuschließen

Romero

Aktiver Benutzer
Beiträge
46
Hallöchen an Euch,

ich bräuchte wieder einmal eure Hilfe.

Speziell geht es grob darum, produktionsfreie Tage summiert von einem Ende-Termin abzuziehen.
Generell habe ich eine Tabelle, welche mir einen Start-Termin zu jedem Auftrag aufgrund einer Durchlaufzeit ermittelt (Ende-Termin - DLZ = Start-Termin).
Leider kann dieser neue Start-Termin auf ein Wochenende, Feiertag und/oder allgemeinen produktionsfreien Tag fallen. Hier soll nun eine Schleife her, die das neue Startdatum um jeweils 1 Tag pro o.g. freien Tag nach vorn schiebt. Also wenn der Auftrag auf ein Wochenende (Sonntag) fällt, dann muss der Starttermin so lange nach vorn geschoben werden, dass es am Ende den Freitag als neuen Starttermin hat. Ist der Freitag ein Feiertag, dann um einen weiteren Tag auf Donnerstag.

Diese Werte der nicht-produktiven-Tage habe ich bereits in einer weiteren Tabelle (Kalender_global) mit 0 oder 2 deklariert (0 = Wochenende / Feiertage, 2 = Betriebsruhe).
Code:
SELECT
            [Kalender].[Tagesdatum],
            [AV].[Auftrag],
            [AV].[Vorgang],
            [AV].[ProduktionsLinie],
            [AV].[Neuer Eckstart]

FROM
            [dbo].[Kalender_global] AS Kalender LEFT OUTER JOIN
            [dbo].[Arbeitsvorrat] AS AV ON [Kalender].[Tagesdatum] = [AV].[Neuer Eckstart]

ORDER BY [Kalender].[Tagesdatum]

GO

Ich weiß, dass es hier über eine WHILE-Schleife zu machen ist.
Komm aber hier grad nicht weiter, wie ich das neue Datum ausgebe bzw. in die bestehende Tabelle einbinde.

LG Romero
 
Werbung:
Schleifen in SQL sollte man generell vermeiden, vor allem dann, wenn man diese vermeiden kann.

Angenommen, ich habe eine Kalender-Tabelle, welche alle Wocheenden und Feiertag enthält:

Code:
edb=*# select * from kalender;
 id |      feiertag       
----+---------------------
  1 | 2021-09-18 00:00:00
  2 | 2021-09-19 00:00:00
  3 | 2021-09-25 00:00:00
  4 | 2021-09-26 00:00:00
(4 rows)

Angenommen, Deine Berechnung des Termines fällt auf den 18.9, ein Sonnabend:

[code]
edb=*# select g.g from (select * from generate_series('2021-09-01'::date,'2021-10-01'::date,'1day'::interval)g) g left join kalender on g.g=kalender.feiertag where kalender.feiertag is null and g.g >= '2021-09-18' limit 1;
          g         
---------------------
 2021-09-20 00:00:00
(1 row)

Also der nächste Arbeitstag wäre dann der 20.9.
 
ach so, du wolltest ja nach vorne schieben:

Code:
edb=*# select g.g from (select * from generate_series('2021-09-01'::date,'2021-10-01'::date,'1day'::interval)g) g left join kalender on g.g=kalender.feiertag where kalender.feiertag is null and g.g <= '2021-09-18' order by g desc limit 1;
          g         
---------------------
 2021-09-17 00:00:00
(1 row)
 
Hallo akretschmer,

vielen Dank für deine Antwort. Auch mit dem 2.Post ;)
Ich habe es mal in mein T-SQL "übersetzt" und habe folgenden Code:
Code:
WITH t AS
(
    SELECT n
    FROM (VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12), (13), (14)) v(n)
)

SELECT
            TOP 1
            Kalender.Tagesdatum,
            Kalender.Wochentagsname,
            Kalender.Tag_Wochenende

FROM
            [dbo].[Kalender_global] AS Kalender LEFT OUTER JOIN
            (
            SELECT DATEADD(DAY, -1 * (t.n), '2021-29-08') AS Test
            FROM t
            ) AS AV ON [Kalender].[Tagesdatum] = AV.Test

WHERE [Kalender].[Tag_Wochenende] <> 1 AND [AV].Test <= '2021-29-08'

ORDER BY Kalender.Tagesdatum DESC

GO

Soweit so gut.

Wie kriege ich aber hier das Datum '2021-29-08' von meiner Tabelle her? Sprich: hier müsste TABELLE1.Spalte_Datum rein, damit er anhand des Ausgangsdatum diese o.g. Berechnung ausführt.
Und dann kann ich dieses neu-ermittelte Datum mit dem Kalender_global erneut verknüpfen und updaten.

LG Romero
 
Werbung:
einfach ;-)

ich habe Tabelle t1:

Code:
edb=*# select * from t1;
          d         
---------------------
 2021-09-05 00:00:00
 2021-09-19 00:00:00
 2021-09-25 00:00:00
(3 rows)

edb=*#

und die Feiertag:

Code:
edb=*# select * from kalender;
 id |      feiertag       
----+---------------------
  1 | 2021-09-18 00:00:00
  2 | 2021-09-19 00:00:00
  3 | 2021-09-25 00:00:00
  4 | 2021-09-26 00:00:00
  5 | 2021-09-05 00:00:00
  6 | 2021-09-06 00:00:00
  7 | 2021-09-04 00:00:00
(7 rows)


Und nun fragen wir das ab:

Code:
edb=*# select * from t1 left join lateral (select g.g from (select * from generate_series('2021-09-01'::date,'2021-10-01'::date,'1day'::interval)g) g left join kalender on g.g=kalender.feiertag where kalender.feiertag is null and g.g <= t1.d order by g desc limit 1) x on true;
          d          |          g         
---------------------+---------------------
 2021-09-05 00:00:00 | 2021-09-03 00:00:00
 2021-09-19 00:00:00 | 2021-09-17 00:00:00
 2021-09-25 00:00:00 | 2021-09-24 00:00:00
(3 rows)

edb=*#

Die Berechnung der Kalendertage des Monats September 2021 ließe sich auch noch dynamisch anhand der Min/Max-Werte aus der t1 - Tabelle machen. Ich weiß aber nicht, ob M$SQL den LATERAL JOIN kennt. Das ist zwar SQL-Standard, aber nicht von allen DB-Systemen unterstützt.
 
Zurück
Oben