Announcement

Collapse
No announcement yet.

Monatliche Arbeitszeit aller Mitarbeiter eines Monats ausgeben

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Monatliche Arbeitszeit aller Mitarbeiter eines Monats ausgeben

    Hi,

    ich bin Fachinformatiker Azubi und mache neben meiner normalen Arbeit hier noch Übungen für die Abschlussprüfung.

    Ich probier mich gerade an den SQL-Aufgaben der Sommerabschlussprüfung 2010, komme aber nicht auf auf ein vollständiges Ergebnis

    Ich hab eine Tabelle "Mitarbeiter" und eine sogenannte Tabelle "Einsatz" die neben der Mitarbeiter id (ma_Id) auch die Anfangszeit, Endzeit und das Datum speichert.

    Mein aktueller Befehl um die Arbeitszeit für einen Monat in Stunden auszugeben sieht so aus:
    Code:
    SELECT mitarbeiter.Ma_Id, nachname, vorname, sec_to_time( sum( time_to_sec( EinsatzBis_Zeit ) - time_to_sec( EinsatzVon_Zeit ) ) ) AS zeit
    FROM mitarbeiter
    JOIN einsatz
    USING ( ma_id ) 
    WHERE year( datum ) =2009
    AND month( datum ) =2
    GROUP BY mitarbeiter.Ma_Id
    Mit diesem Befehl bekomme ich jetzt alle Mitarbeiter die mindestens einen Einsatz im Februar 2009 hatten.
    Wie muss ich den Befehl aber verändern um auch die anderen Mitarbeiter, die keine Einsätze hatten, mit einer Arbeitszeit von (00:00:00) zu erhalten (ich möchte jedoch kein null als Ergebnis)?

    Es müsste doch mit einem Befehl möglich sein, oder irre ich mich da.

    Gruß
    Erik "EMMachine"

  • #2
    Du musst Deinen inner join, also das ".. JOIN einsatz USING ..", gegen einen outer join ersetzen.
    Außerdem empfehle ich Dir, Deine group by Klausel auf alle nicht aggregierten Felder zu vervollständigen.
    Zuletzt editiert von defo; 08.03.2012, 15:29.
    Gruß, defo

    Comment


    • #3
      Okay, ich hab den Befehl jetzt dazu abgeändert.
      Code:
      SELECT mitarbeiter.Ma_Id, nachname, vorname, sec_to_time( sum( time_to_sec( EinsatzBis_Zeit ) - time_to_sec( EinsatzVon_Zeit ) ) ) AS zeit
      FROM mitarbeiter left outer join einsatz on mitarbeiter.ma_id = einsatz.ma_id and year( datum ) =2009
      AND month( datum ) =2 
       group by mitarbeiter.ma_id
      Ich bin aber mit dem Ergebnis immer noch nicht ganz zufrieden. Ich bekomm zwar jetzt alle Mitarbeiter. Gibt es aber keine Möglichkeit, dass statt dem "NULL" bei der Ausgabe zeit einfach eine 0 (oder 00:00) stehen könnte. (Oder müsste dafür zu jeder Person ein Datensatz pro Monat existieren, bei dem eine Zeit von 0 rauskommt.

      Es gibt auch eine andere Aufgabe, bei der der Resturlaub ausgerechnet werden soll. Ich dachte eigentlich, dass ich auf eine ähnliche Art vorgehen könnte, wenn ich aber "NULL" rausbekomme, kann ich ja schlecht was in einer SQL-Funktion ausrechnen.

      Warum soll ich eigenlich mehr Variablen ins Group by setzen? Die Variable "Ma_Id" ist pro Person eindeutig. Ich hab schon Fälle gesehen wo es nötig war, aber warum hier?

      Comment


      • #4
        statt des Nullwertes kannst Du folgende Funktion nehmen:
        http://dev.mysql.com/doc/refman/5.0/...unction_ifnull

        Das Group by ist bei mySQL sehr "speziell" ausgelegt, nett gesagt großzügig, m.E. verleitet es zur Schlamperei.
        Kannst Du ja selber mal nachschlagen, was es damit auf sich hat. Oder andersrum, was macht eigentlich ein "group by"?
        Gruß, defo

        Comment


        • #5
          Okay danke, jetzt ist der Befehl so wie er sein soll. Jetzt müsste die andere Aufgabe, die ich genannt hatte auch ohne große Probleme lösbar sein.

          Zum Thema group by. Korrigier mich wenn ich falsch liege.
          Ein Group by fügt alle Werte der Reihenfolge nach zu Gruppen zusammen. Wenn ich also nach der ma_id gruppierte und summiere werden alle Datensätze mit der gleichen ma_id zusammengruppiert. In einer anderen Aufgabe war ne Gruppierung nach Fehlgrund und Person.
          - Wenn ich nur nach Fehlgrund gruppiere und die Tage summiere werden nur alle gleichen Fehlgründe summiert (unabhängig nach Person, wobei die erste Person eingesetzt wird)
          - wenn ich nur nach Person gruppiere werden alle Tage nach Person summiert (unabhängig vom Fehlgrund, wobei nur der erste Fehlgrund eingetragen wird)
          - wenn ich nach beidem gruppiere werden alle Datensätze addiert, bei denen die Person und der Fehlgrund gleich ist.
          Das stimmt doch, ist es wegen den ersten beiden Fällen?

          Comment


          • #6
            Zum Thema Gruppierung:

            Der aktuelle SQL-Standard besagt:
            If T is a grouped table, then let G be the set of grouping columns of T. In each <value expression> contained in <select list>, each column reference that references a column of T shall reference some column C that is functionally dependent on G or shall be contained in an aggregated argument of a <set function specification> whose aggregation query is QS.
            Zu gut deutsch: In der SELECT-Liste der Abfrage dürfen nur Ausdrücke auftauchen, die a) in der GROUP BY-Klausel stehen, b) von den Ausdrücken in der GROUP BY-Klausel funktional abhängig sind oder c) Aggregiert sind.
            Damit ist deine Gruppierung über die ma_id nach diesem Standard korrekt, die aufgeführten Gruppierungen mit Fehlgrund und Person dagegen nicht. Hier sind jeweils Fehlgrund bzw. Person NICHT funktional abhängig.

            Das Problem: Ist die Umsetzung bzw. zuverlässige Erkennung funktionaler Abhängigkeit. Aus diesem Grund gibt es kein DBMS, welches den o.g. Standard vernünftig umsetzt. Alle DBMS unterstützen dagegen den Standard von 1992 der mehr oder weniger einfach besagt, dass alle nichtaggregierten Felder aus dem SELECT auch im GROUP BY aufgeführt werden müssen.

            Einzige Ausnahme: MySQL! Die Entwickler von MySQL überlassen die Entscheidung nach funktionaler Abhängigkeit dem SQL-Programmierer und damit auch solche sinnfreien Konstrukte wie:
            - Wenn ich nur nach Fehlgrund gruppiere und die Tage summiere werden nur alle gleichen Fehlgründe summiert (unabhängig nach Person, wobei die erste Person eingesetzt wird)
            und
            - wenn ich nur nach Person gruppiere werden alle Tage nach Person summiert (unabhängig vom Fehlgrund, wobei nur der erste Fehlgrund eingetragen wird)
            zu.
            Die Ergebnisse solcher Abfragen sind z.T. nicht nachvoll- und vor allem nicht interpretierbar.

            Fazit: Wenn du SQL-Code schreiben möchtest, der auf verschiedenen DBMS einsetzbar ist und nachvollziehbare Ergebnisse liefert, dann solltest du dich an den 1992er Standard halten!

            Gruß Falk
            Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

            Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

            Comment

            Working...
            X