SQL-Funktion – Ermittlung der Überlappung von 2 Zeiträumen

Ab und an geht es mal darum in einer Datenbank den Überlappungs-Zeitraum von 2 Zeiträumen zu ermitteln, oder auch nur ob 2 Zeiträume überhaupt überlappen. Heute stand ich vor dieser Problematik und habe auch keine eingebaute Funktion im MS-SQL-Server gefunden. Die folgenden 2 Funktionen, alle Angaben ohne Gewähr, führen jedenfalls bei mir zum gewünschten Ergebnis:

Überprüfung ob 2 Zeiträume überlappen

ALTER FUNCTION [dbo].[CheckPeriodOverlap] 
(
 -- Add the parameters for the function here
 @Period1Start date,
 @Period1End date,
 @Period2Start date,
 @Period2End date
)
RETURNS bit
AS
BEGIN
 DECLARE @IsOverlapping bit =
 case 
 when 
 @Period1Start <= @Period2Start
 AND @Period1End >= @Period2End
 then 1
 when 
 @Period1Start <= @Period2Start
 AND @Period1End >= @Period2Start
 AND @Period1End <= @Period2End
 then 1
 when 
 @Period1Start >= @Period2Start
 AND @Period1End <= @Period2End
 then 1
 when 
 @Period1Start <= @Period2End
 AND @Period1End >= @Period2End
 then 1
 else 0
 end
-- Return the result of the function
RETURN @IsOverlapping
END

Ermittlung der Tage, die 2 Zeiträume überlappen

ALTER FUNCTION [dbo].[PeriodOverlappingDays]
(
 -- Add the parameters for the function here
 @Period1Start date
 ,@Period1End date
 ,@Period2Start date
 ,@Period2End date
)
RETURNS int
AS
BEGIN
 declare @OverlappingDays int = 0
 declare @p1_1 date = case 
when @Period1Start < @Period1End 
 then @Period1Start else @Period1End end
 declare @p1_2 date = case 
when @Period1Start < @Period1End 
 then @Period1End else @Period1Start end
 declare @p2_1 date = case 
when @Period2Start < @Period2End 
 then @Period2Start else @Period2End end
 declare @p2_2 date = case 
when @Period2Start < @Period2End 
 then @Period2End else @Period2Start end
 declare @IsOverlap bit = dbo.CheckPeriodOverlap(@p1_1, @p1_2, @p2_1, @p2_2)
if @IsOverlap = 0
 begin
 set @OverlappingDays = 0
 end
 else set @OverlappingDays = 
 case 
 --#1 P1 beginnt vorher und endet in P2
 when @p1_1 < @p2_1 and @p1_2 between @p2_1 and @p2_2
 then datediff(d, @p2_1, @p1_2) + 1
 --#2 P1 beginnt in P2 und endet nach P2
 when @p1_1 between @p2_1 and @p2_2 and @p1_2 > @p2_2
 then datediff(d, @p1_1, @p2_2) + 1
 --#3 P1 beginnt end endet innerhalb P2
 when @p1_1 between @p2_1 and @p2_2 and @p1_2 between @p2_1 and @p2_2
 then datediff(d, @p1_1, @p1_2) + 1
 --#4 P1 beginnt vor und endet nach P2
 when @p1_1 < @p2_1 and @p1_2 > @p2_1
 then datediff(d, @p2_1, @p2_2) + 1
 --#5 P1 und P2 sind identisch
 when @p1_1 = @p2_1 and @p1_2 = @p2_2
 then datediff(d, @p2_1, @p2_2) + 1
 --#6 P1 beginnt mit P2 und endet später
 when @p1_1 = @p2_1 and @p1_2 > @p2_2
 then datediff(d, @p2_1, @p2_2) + 1
 --#7 P1 beginnt mit P2 und endet früher
 when @p1_1 = @p2_1 and @p1_2 < @p2_2
 then datediff(d, @p1_1, @p1_2) + 1
 --#8 P1 beginnt vor P2 und endet mit P2
 when @p1_1 < @p2_1 and @p1_2 = @p2_2
 then datediff(d, @p2_1, @p2_2) + 1
 --#9 P1 beginnt nach P2 und endet mit P2
 when @p1_1 > @p2_1 and @p1_2 = @p2_2
 then datediff(d, @p1_1, @p1_2) + 1
 else null end
-- Return the result of the function
 RETURN @OverlappingDays
END

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert