Vereinfachen: MySQL

Pol

Mitglied
Hallo
Ich verwende die folgende Abfrage in einem View. In diesem View verwende ich immer wieder die gleichen Berechnungen. Ich weiss es nicht, ob einen besseren Weg geben würde, bestimmte Ausdrücke zu vereinfachen.
Zum Beispiel Variante?

Die Berechnungen sind für Erfassung der Arbeitszeit gedacht. Natuerlich auch die Vorschlaege für die Berechnung der Tagesarbeitszeit sind willkommen.

Danke.
Pol
SQL:
 Sum(((Time_To_Sec(TimeDiff(arbeitszeit.ezeit, arbeitszeit.szeit)) / 3600) -
  arbeitszeit.arbzpause)) As Netto,

  ((Sum((Case
    When ((arbeitszeit.szeit >= arbeitszeit.gs) And (arbeitszeit.ezeit <=
    arbeitszeit.ge) And (DayOfWeek(arbeitszeit.arbzstart) <> 1) And
    (DayOfWeek(arbeitszeit.arbzstart) <> 7) And (arbeitszeit.arbszart <>
    'Feiertag')) Then ((Time_To_Sec(TimeDiff(arbeitszeit.ezeit,
    arbeitszeit.szeit)) / 3600) - arbeitszeit.arbzpause)
    When ((arbeitszeit.szeit < arbeitszeit.gs) And (arbeitszeit.ezeit >
    arbeitszeit.gs) And (arbeitszeit.ezeit <= arbeitszeit.ge) And
    (DayOfWeek(arbeitszeit.arbzstart) <> 1) And
    (DayOfWeek(arbeitszeit.arbzstart) <> 7) And (arbeitszeit.arbszart <>
    'Feiertag')) Then ((Time_To_Sec(TimeDiff(arbeitszeit.ezeit, arbeitszeit.gs))
    / 3600) - arbeitszeit.arbzpause)                                                    
    When ((arbeitszeit.szeit >= arbeitszeit.gs) And (arbeitszeit.szeit <
    arbeitszeit.ge) And (arbeitszeit.ezeit > arbeitszeit.ge) And
    (DayOfWeek(arbeitszeit.arbzstart) <> 1) And
    (DayOfWeek(arbeitszeit.arbzstart) <> 7) And (arbeitszeit.arbszart <>
    'Feiertag')) Then ((Time_To_Sec(TimeDiff(arbeitszeit.ge, arbeitszeit.szeit))
    / 3600) - arbeitszeit.arbzpause)
    When ((DayOfWeek(arbeitszeit.arbzstart) = 1) Or
    (DayOfWeek(arbeitszeit.arbzstart) = 7) Or
    (arbeitszeit.arbszart = 'Feiertag')) Then arbeitszeit.abszsollstd Else 0
  End)) - arbeitszeit.abszsollstd) - Sum(If((arbeitszeit.arbszart =
  'Kompensation'), ((Time_To_Sec(TimeDiff(arbeitszeit.ezeit, arbeitszeit.szeit))
  / 3600) - arbeitszeit.arbzpause), 0))) As PlusMinus,
 
Zuletzt bearbeitet von einem Moderator:
Ich habe mal dein text in SQL-Tags gesetzt. Leider wird er dadurch nicht lesbarer
Darum mein erster Vorschlag: http://www.tutorials.de/content/1550-php-sql-statement-php-lesbar-darstellen.html

Einmal durch einen SQL-Formatter gequetscht zeigt das eigentliche Ausmass der Formel
SQL:
SUM(
    (
        (
            time_to_sec(
                timediff(
                    arbeitszeit.ezeit, arbeitszeit.szeit
                )
            ) / 3600
        ) - arbeitszeit.arbzpause
    )
) AS netto, 
(
    (
        SUM(
            (
                CASE WHEN (
                    (
                        arbeitszeit.szeit >= arbeitszeit.gs
                    ) 
                    AND (
                        arbeitszeit.ezeit <= arbeitszeit.ge
                    ) 
                    AND (
                        dayofweek(arbeitszeit.arbzstart) <> 1
                    ) 
                    AND (
                        dayofweek(arbeitszeit.arbzstart) <> 7
                    ) 
                    AND (
                        arbeitszeit.arbszart <> 'Feiertag'
                    )
                ) THEN (
                    (
                        time_to_sec(
                            timediff(
                                arbeitszeit.ezeit, arbeitszeit.szeit
                            )
                        ) / 3600
                    ) - arbeitszeit.arbzpause
                ) WHEN (
                    (
                        arbeitszeit.szeit < arbeitszeit.gs
                    ) 
                    AND (
                        arbeitszeit.ezeit > arbeitszeit.gs
                    ) 
                    AND (
                        arbeitszeit.ezeit <= arbeitszeit.ge
                    ) 
                    AND (
                        dayofweek(arbeitszeit.arbzstart) <> 1
                    ) 
                    AND (
                        dayofweek(arbeitszeit.arbzstart) <> 7
                    ) 
                    AND (
                        arbeitszeit.arbszart <> 'Feiertag'
                    )
                ) THEN (
                    (
                        time_to_sec(
                            timediff(
                                arbeitszeit.ezeit, arbeitszeit.gs
                            )
                        ) / 3600
                    ) - arbeitszeit.arbzpause
                ) WHEN (
                    (
                        arbeitszeit.szeit >= arbeitszeit.gs
                    ) 
                    AND (
                        arbeitszeit.szeit < arbeitszeit.ge
                    ) 
                    AND (
                        arbeitszeit.ezeit > arbeitszeit.ge
                    ) 
                    AND (
                        dayofweek(arbeitszeit.arbzstart) <> 1
                    ) 
                    AND (
                        dayofweek(arbeitszeit.arbzstart) <> 7
                    ) 
                    AND (
                        arbeitszeit.arbszart <> 'Feiertag'
                    )
                ) THEN (
                    (
                        time_to_sec(
                            timediff(
                                arbeitszeit.ge, arbeitszeit.szeit
                            )
                        ) / 3600
                    ) - arbeitszeit.arbzpause
                ) WHEN (
                    (
                        dayofweek(arbeitszeit.arbzstart) = 1
                    ) 
                    OR (
                        dayofweek(arbeitszeit.arbzstart) = 7
                    ) 
                    OR (
                        arbeitszeit.arbszart = 'Feiertag'
                    )
                ) THEN arbeitszeit.abszsollstd ELSE 0 END
            )
        ) - arbeitszeit.abszsollstd
    ) - SUM(
        IF(
            (
                arbeitszeit.arbszart = 'Kompensation'
            ), 
            (
                (
                    time_to_sec(
                        timediff(
                            arbeitszeit.ezeit, arbeitszeit.szeit
                        )
                    ) / 3600
                ) - arbeitszeit.arbzpause
            ), 
            0
        )
    )
) AS plusminus,

Sorry, aber ohne weitere Erklärungen verstehe ich diese Monsterformel nicht
Mach doch mal Kommentare rein.

Also, ich nehme mal die erste kurze Formel
SQL:
SUM(
    (
        (
            time_to_sec(
                timediff(
                    arbeitszeit.ezeit, arbeitszeit.szeit
                )
            ) / 3600
        ) - arbeitszeit.arbzpause
    )
) AS netto,
item: Da hats bereits in der äussersten Stufe eine Klammer zuviel.

item: Dann rate ich dir, die Berechnung in ein Subquery zu setzen und erst darüber dann die Summe zu bilden. Wird übersichtlicher.
SQL:
SELECT
	SUM(a.arbz) - arbzpause AS netto
FROM
	(SELECT 
		(time_to_sec(timediff(ezeit, szeit)) / 3600) AS arbz,
		arbzpause
	FROM arbeitszeit)  AS a

item: Arbeite mit Tabellenaliassen. Das verkürzt die Tabellennamen. Eigentlich kannst du diese auch ganz weglassen. Es ist ja alles aus derselben Quelle

item: Arbeite mit dem Befehl BETWEEN. Oder in deinem Fall noch besser mit GREATEST() und LEAST() arbeiten: MySQL Perioden vergleichen. (gs,ge mit eZeit,sZeit vergleichen)

item: Du hast so viele unnötige Klamern die den Code nur aufblasen. Weg damit!



Nachtrag:
Und das plusminus mal umformtiert, ohne zu versteehn was da genau läuft.
SQL:
SUM (
    CASE 
        WHEN 
            a.szeit >= a.gs
            AND a.ezeit <= a.ge
            AND dayofweek(a.arbzstart) <> 1
            AND dayofweek(a.arbzstart) <> 7
            AND a.arbszart <> 'Feiertag'
        THEN
        	time_to_sec(timediff(a.ezeit, a.szeit)) / 3600 - arbeitszeit.arbzpause
        WHEN
            a.szeit < a.gs
            AND a.ezeit > a.gs
            AND a.ezeit <= a.ge
            AND dayofweek(a.arbzstart) <> 1
            AND dayofweek(a.arbzstart) <> 7
            AND a.arbszart <> 'Feiertag'
        THEN 
            time_to_sec(timediff(a.ezeit, a.gs)) / 3600 - a.arbzpause
        WHEN
            a.szeit >= a.gs
            AND a.szeit < a.ge
            AND a.ezeit > a.ge
            AND dayofweek(a.arbzstart) <> 1
            AND dayofweek(a.arbzstart) <> 7
            AND a.arbszart <> 'Feiertag'
        THEN 
            time_to_sec(timediff(a.ge, a.szeit)) / 3600 - a.arbzpause
        WHEN
            dayofweek(a.arbzstart) = 1
            OR dayofweek(a.arbzstart) = 7
            OR a.arbszart = 'Feiertag'
        THEN 
            a.abszsollstd 
        ELSE 
            0 
    END 
    - a.abszsollstd
    - IF(
	   a.arbszart = 'Kompensation', 
        time_to_sec(timediff(a.ezeit, a.szeit)) / 3600 - a.arbzpause,
        0
    )
) AS plusminus
 
Zuletzt bearbeitet von einem Moderator:
Hallo Yaslaw
Danke sehr für deinen Input. In allen Punkten hast du recht. Ich suche eben Vorschläge, um die Abfrage zu verenfachen oder zu übersichtlicher machen.
Danke
Pol
 
Zurück