Ich habs trotzdem nochmal versucht
/* create table #abwesend (mitarbeiter varchar(10), unterbrechungsgrund varchar(10), datum date)
insert into #abwesend
values
('Huber','Urlaub','20230317'),
('Huber','Urlaub','20230318'),
('Huber','Urlaub','20230403'),
('Huber','Urlaub','20230404'),
('Maier','krank','20230317'),
('Maier','Urlaub','20230318'),
('Müller','krank','20230317'),
('Müller','Urlaub','20230525'),
('Müller','Urlaub','20230526')
*/
DECLARE @StartDate DATE = '20230317';
DECLARE @CutoffDate DATE = DATEADD(DAY, - 1, DATEADD(YEAR, 1, @StartDate));;
WITH seq (n)
AS (
SELECT 0
UNION ALL
SELECT n + 1
FROM seq
WHERE n < DATEDIFF(DAY, @StartDate, @CutoffDate)
)
,d (d) -- Kalender ohne Wochenende
AS (
SELECT DATEADD(DAY, n, @StartDate)
FROM seq
)
,kalender (
d
,mitarbeiter
)
AS (
SELECT d
,mitarbeiter
FROM d
CROSS JOIN (
SELECT DISTINCT mitarbeiter
FROM #abwesend
) AS x where DATEPART(WEEKDAY,d) not in (1,7) -- für Wochenende keinen Tag in der Tabelle erzeugen
)
,letzttag ( mitarbeiter ,d)--Tabelle mit Erster Arbeitstag
AS
(
SELECT KALENDER.mitarbeiter
,MIN(d)
FROM KALENDER
LEFT JOIN #abwesend a ON a.datum = d
AND kalender.mitarbeiter = a.mitarbeiter
WHERE datum IS NULL
GROUP BY KALENDER.mitarbeiter
)
SELECT *
FROM #abwesend
WHERE EXISTS (
SELECT MAX(datum) maxdat
,ab.mitarbeiter
FROM #abwesend ab
JOIN letzttag ON letzttag.mitarbeiter = #abwesend.mitarbeiter
WHERE datum < d
GROUP BY ab.mitarbeiter
HAVING ab.mitarbeiter = #abwesend.mitarbeiter
AND MAX(datum) = #abwesend.datum
)
OPTION (MAXRECURSION 0)
Der erste Teil erzeugt einen Kalender (für 1 Jahr) ohne Wochenende, Da könnte man auch auf das höchste Datum +1 Tag der Abwesenheitstabelle gehen.
Was klar nicht abgedeckt ist sind die Feiertage.
Dann hol ich mir das erste Datum wenn die Leute wieder da sind und dann aufgrund dessen wieder das letzte an dem sie gefehlt haben mitsamt dem Grund.
Verknüpft habe ich über die Mitarbeiternamen, da gibts sicher auch was eindeutiges. aber als Idee sollte es reichen.