Keine Ahnung wie ich eine lokale Variable aktualisieren kann und diese im SELECT ausgeben kann

Christian_T

Benutzer
Beiträge
8
Hallo Leute,

ich bin ein SQL-Rookie und habe folgendes Problem:

Quell-Tabelle:
Mitarbeiter | Abwesenheitsgrund | Datum
Meier | Urlaub | 12.08.2015
Meier | Urlaub | 13.08.2015
Meier | Urlaub | 14.08.2015
Meier | Urlaub | 17.08.2015
Meier | Krank | 18.08.2015
Meier | Urlaub | 19.08.2015

Zum 15. + 16. (Sa und So) gibt es keine Eintragungen, da keine Arbeitstage.

Ich möchte mit einer Stored Procedure folgende Zieltabelle erhalten, wenn ich die Stored Procedure mit dem heutigen Datum 12.08.2015 aufrufe:
Mitarbeiter | Abwesenheitsgrund | abwesendBisEinschliesslich
Meier | Urlaub | 17.08.2015

Kann mir einer von Euch sagen mit welchen Methoden ich diese Zieltabelle erhalten kann?

Danke im voraus,
Christian
 
Werbung:
Das ist "fast" ganz einfach:
Code:
/*
CREATE TABLE test(
   Mitarbeiter VARCHAR(20),
   Abwesenheitsgrund VARCHAR(10),
   Datum DATETIME
   );

INSERT INTO test VALUES ('Meier','Urlaub','2015-12-08 00:00:00.000');
INSERT INTO test VALUES ('Meier','Urlaub','2015-13-08 00:00:00.000');
INSERT INTO test VALUES ('Meier','Urlaub','2015-14-08 00:00:00.000');
INSERT INTO test VALUES ('Meier','Urlaub','2015-17-08 00:00:00.000');
INSERT INTO test VALUES ('Meier','Urlaub','2015-19-08 00:00:00.000');
INSERT INTO test VALUES ('Meier','Krank','2015-18-08 00:00:00.000');

SELECT   *
FROM   test
*/
WITH t AS (
   SELECT   t1.Datum AS Datum_von,
       t1.Datum AS Datum_bis,
       cast(convert(VARCHAR(10),t1.Datum,104) AS VARCHAR(1000)) AS Pfad,
       0 AS [Level],
       t1.Abwesenheitsgrund,
       t1.Mitarbeiter
   FROM   test t1
   LEFT JOIN test t2
   ON     t1.Datum = (   CASE
               WHEN   datepart(dw,t2.Datum+1) BETWEEN 1 AND 5
               THEN   t2.Datum+1
               WHEN   datepart(dw,t2.Datum+1) = 6
               THEN   t2.Datum+3
               WHEN   datepart(dw,t2.Datum+1) = 7
               THEN   t2.Datum+2
               END )
   AND     t1.Abwesenheitsgrund = t2.Abwesenheitsgrund
   AND     t1.Mitarbeiter = t2.Mitarbeiter
   WHERE   t2.Datum IS NULL
   UNION ALL
   SELECT   t.Datum_von AS datum_von,
       t3.Datum AS Datum_bis,
       cast(Pfad + '/' + convert(VARCHAR(10),t3.Datum,104) AS VARCHAR(1000)) AS Pfad,
       [Level] + 1 AS [Level],
       t.Abwesenheitsgrund,
       t.Mitarbeiter
   FROM   test t3
   JOIN   t
   ON     t3.Datum = (   CASE
               WHEN   datepart(dw,t.Datum_bis+1) BETWEEN 1 AND 5
               THEN   t.Datum_bis+1
               WHEN   datepart(dw,t.Datum_bis+1) = 6
               THEN   t.Datum_bis+3
               WHEN   datepart(dw,t.Datum_bis+1) = 7
               THEN   t.Datum_bis+2
               END )
   AND     t3.Abwesenheitsgrund = t.Abwesenheitsgrund
   AND     t3.Mitarbeiter = t.Mitarbeiter
   )
SELECT   t.Mitarbeiter,
     t.Datum_von,
     t.Datum_bis,
     t.Abwesenheitsgrund,
     t.[Level] + 1 AS Dauer,
     t.Pfad
FROM   t
WHERE NOT EXISTS (   SELECT   1
           FROM   t t4
           WHERE   t4.Datum_von = t.Datum_von
           AND     t4.Abwesenheitsgrund = t.Abwesenheitsgrund
           AND     t4.Mitarbeiter = t.Mitarbeiter
           AND     t4.Datum_bis > t.Datum_bis )
ORDER BY t.Mitarbeiter,t.Datum_von
OPTION (MAXRECURSION 200)
Ich verwende keine Prozedur sondern baue alles in eine CTE-Abfrage, die sich zusammenhängende Tage nach Mitarbeiter und Abwesenheitsgrund sucht und diese ähnlich einer Baumstruktur mit Unterelementen verkettet. Die Spalten für Pfad und Level sind eigentlich nur zur Veranschaulichung. Die Tage Samstag und Sonntag handle ich in diesem Fall mit einer CASE-Schleife ab um zum nächsten Arbeitstag zu springen. Da ich schon viel zu lange an dem Code geschraubt habe, spare ich mir jetzt mal tiefergehende Ausführungen. Darüber könnte man vermutlich Bücher schreiben und das ist auch für Profis sicherlich nicht einfach, ich grübel da jedes mal drüber.
 
Zuletzt bearbeitet:
Werbung:
Ich würde das gar nicht als SP machen, du kannst auch eine View anlegen und darauf dann einfach nach Datum oder nach Mitarbeiter abfragen.
 
Zurück
Oben