thejoker2305
Goto Top

MS SQL Nachtzuschläge aus Start und Endzeit bestimmen

Hallo zusammen,

ich habe folgende Herausforderung:

Es sollen aus Start und Endzeiten die Zeiten im jeweiligen Nachtzuschlag errechnet werden.

Beispiel 1 Start 19:21 Ende 6:21
Beispiel 2 Start 03:02 Ende 13:05

Nachtzuschlagzeitraum 1 0-4 Uhr
Nachtzuschlagzeitraum 2 4-5 Uhr
Nachtzuschlagzeitraum 3 20-0 Uhr
Nachtzuschlagzeitraum 4 0-4 Uhr (Folgetetag)
Nachtzuschlagzeitraum 5 4-5 Uhr (Folgetetag)

Im Beispiel 1 soll folgendes rauskommen:
NZ3 240 Minuten
NZ4 240 Minuten
NZ5 60 Minuten

Im Beispiel 2 soll folgendes rauskommen:
NZ1 58 Minuten
NZ2 60 Minuten

Um die Zeiten des NZ1 zu ermitteln bin ich so vorgegangen:
SELECT 
     CASE WHEN (start <= '04:00:00' and ende >'00:00:00') and ende < '04:00:00' then ende-start else 0 end +  
        CASE WHEN (start <= '04:00:00' and ende >'00:00:00') and ende > '04:00:00' then datediff(minute,start,'04:00:00') else 0 end NZ_0_4  
FROM ...

Bei den anderen Nachtzuschlagzeiten würde ich ählich vorgehen und die zeitlichen Überschneidungen zu ermitteln.

Ich habe leider noch keinen einfacheren Weg gefunden, da die Datediff-Funktion ja nur den Unterschied zwischen zwei Zeitpunkten, jedoch keine zwei Zeiträume mit einander berechnen kann.

Gibt es eine Funktion hierfür oder einen einfacherem Weg?

Besten Dank vorab

thejoker2305

Content-Key: 1113891340

Url: https://administrator.de/contentid/1113891340

Printed on: April 28, 2024 at 21:04 o'clock

Member: em-pie
em-pie Aug 02, 2021 updated at 09:54:52 (UTC)
Goto Top
Moin,

aus meiner Sicht wirst du um den "Aufwendigen Weg" nicht herum kommen.
Ich würde allerdings die Zeiten am Ende mit "DateAdd" addieren sowie die ganze Berechnung in eine UDF auslagern.

Das hat den Vorteil, dass
a) du dein primäres Statement übersichtlich hältst
b) du die Berechnung auch in anderen Queries nutzen könntest.

Als Parameter definierst du dann einen Start- und einen Endwert und würdest die dann so erzeugen...
CREATE FUNCTION udf_calcZulage(@start datetime, @end datetime)
RETURNS TABLE
AS
RETURN INT
AS
(
 SELECT 
  zuschlag = CASE WHEN ... THEN ... ELSE ... END
);

.. und so aufrufen (als Beispiel)
SELECT
  ...
  , Zulage = [dbo].[udf_calcZulage](start, end)
FROM
 myTable

Hier mal noch eine weitere, kleine Hilfe, auch wenn es sich hier nicht um Minuten handelt: https://blog.sqlauthority.com/2007/05/05/sql-server-udf-user-defined-fun ...

Gruß
em-pie
Member: TheJoker2305
TheJoker2305 Aug 02, 2021 at 10:20:14 (UTC)
Goto Top
Hallo em-pie,

final wird es in eine Funktion eingebaut. Als ersten schritt dachte ich nur an die Funktion datediff, aber die kann ja nur mit zwei Zeitpunkten und nicht mit zwei Zeiträumen umgehen.

Danke schon mal bis hierhin face-smile

Gruß
thejoker2305
Member: ukulele-7
ukulele-7 Aug 02, 2021 at 12:48:03 (UTC)
Goto Top
Es könnte ein bisschen einfacher werden mit greatest() und least() wenn dieses Killer Feature mal in MSSQL kommt:
https://en.dirceuresende.com/blog/sql-server-the-new-greatest-and-least- ...
Im wesentlichen bleibt es aber wohl erstmal bei einem CASE Konstrukt.