mit Zeiten rechnen - Ermittlung der Arbeitszeit aus MySQL-Tabelle

Du könntest mal versuchen, mit SELECT *, SEC_TO_TIME ... AS zeit ... das gleiche zu erreichen. Ich weiss aber nicht, ob das zulässig ist.

Mit dem Ausdruck führst Du der Ergebnistabelle ein Feld mit Aliasnamen (AS) zu denen aus der Tabelle hinzu. Dieses neue Feld wirst Du mit * nicht erreichen.

Ich habe mir mittlerweile angewöhnt die Felder immer explizit auszuwählen und kann das nur empfehlen. Du hast direkt in Deinem PHP-Code die Übersicht, welche Felder Dir zur Verfügung stehen, ohne nebenbei in die Datenbank schauen zu müssen. Der wesentliche Vorteil ist jedoch, dass Du die Performance des Querys steigerst, wenn Du nicht alle Felder brauchst und nur die benötigten auflistest.

Gruß hpvw
 
Hallo,

ja stimmt - es macht ja auch durchaus Sinn wenn man nur die Felder auswählt die man braucht. Ich werde mir den Tipp zu Herzen nehmen und das künftig so machen.

So und schon wieder hat sich dich nächste Frage aufgeworfen.

Kann ich mehrere Datumsfunktionen nicht in eine Abfrage schreiben?
Wenn ich z.b. folgenden Code in die Abfrage schreibe funktioniert es:
Code:
SELECT 
id,
user,
kommen,
gehen,
status,
SEC_TO_TIME( UNIX_TIMESTAMP( gehen ) - UNIX_TIMESTAMP( kommen ) ) AS zeit
FROM `zeitkarte` 
WHERE user='dani'
LIMIT 0 , 30

wenn ich dann folgende Abfrage schreibe funktionier es auch:
Code:
SELECT 
id,
user,
kommen,
gehen,
status,
DATE_FORMAT(kommen, '%d.%m.%Y') AS tage
FROM `zeitkarte` 
WHERE user='dani'
LIMIT 0 , 30

Wenn ich jedoch folgendes schreibe:
Code:
SELECT 
id,
user,
kommen,
gehen,
status,
SEC_TO_TIME( UNIX_TIMESTAMP( gehen ) - UNIX_TIMESTAMP( kommen ) ) AS zeit
AND DATE_FORMAT(kommen, '%d.%m.%Y') AS tage
FROM `zeitkarte` 
WHERE user='dani'
LIMIT 0 , 30
dann funktioniert es nicht mehr.

Ich habe auch schon versucht das AND aus der Abfrage raus zu nehmen - aber ich bekomme immer einen Syntax-Fehler.
Und mit den Fehlerbeschreibungen von phpmyadmin kann ich nicht sehr viel anfangen.
Gibt es da eine Referenz im Netzt wo solche Leute wie ich auch selbst auf den Fehler kommen können.

Kann man die Anfragen nicht kombinieren?

Vielen Dank im voraus für die Hilfe
 
hpvw hat gesagt.:
Mit dem Ausdruck führst Du der Ergebnistabelle ein Feld mit Aliasnamen (AS) zu denen aus der Tabelle hinzu.
Mit dem Hinweis sollte es möglich sein, den Fehler selbst zu finden.
Du willst der Abfrage nun noch ein Feld hinzufügen. Dieses trennt man von den anderen Feldern mit einem Komma ab, wie man es mit allen Feldern tut, die man einzeln aufführt.
Mit dem logischen Operator AND hat das nichts zu tun.

Ansonsten hilft auch die Sprachreferenz.

Gruß hpvw
 
Hallo mein Held,

VIELEN VIELEN DANK!

Es funktioniert - und jetzt habe ich das dumpfe Gefühl das ich langsam durchsteige.

Ein Problem habe ich noch - aber das kann ich villeicht selber lösen - ausserdem kommt das erst in der weiteren Programmierung auf mich zu - da mache ich mir jetzt noch keine Sorgen drüber.

Danke nochmals
 
Hallo,

so nun bin ich wieder mal an meine Grenzen gestossen.
Ich habe es soweit geschaft das die Zeiten in der Tabelle eingetragen werden und die Zeitdiffernz ausgerechnet und auch eingetragen wird.
Ausserdem habe ich eine neue Tabellenspalte eingefügt diese heisst "zeitstempel" in dieser Spalte speichere ich die jeweils gearbeiteten Sekunden ab.

So jetzt bin ich drauf gekommen das man ja über SUM() eine gesamtsumme bilden kann.

Wenn ich jetzt folgendes an MySQL sende:
Code:
SELECT user, SUM( zeitstempel ) 
FROM zeitkarte
GROUP BY user
LIMIT 0 , 500
dann bekomme ich ja die Summen der Zeitstemple der Nutzer ausgeworfen.

Jetzt möchte ich aber nur einen bestimmten User zu einem bestimmten Zeitpunkt auswerfen - jetzt mache ich folgendes:
Code:
SELECT user, SUM( zeitstempel ) 
FROM zeitkarte
WHERE user = 'dani'
AND MONTH( kommen ) =5
AND YEAR( kommen ) =2005
GROUP BY user
LIMIT 0 , 500
Also User = dani im Mai 2005 das funktioniert ja auch noch.

Wie bekomme ich jetzt aber aus den zusammengezählten Sekunden - wieder eine Zeit in (evtl. tage) stunden und minuten?
Das ganze brauche ich für die Auswertung am Monatsende
 
dwex hat gesagt.:
Wie bekomme ich jetzt aber aus den zusammengezählten Sekunden - wieder eine Zeit in (evtl. tage) stunden und minuten?
Das geht mit der Funktion SEC_TO_TIME, die wir oben auch verwendet haben.

Außerdem möchte ich Dich noch darauf hinweisen, dass es im Sinne der Normalisierung schlechtes Datenbankdesign ist, Felder in der Datenbank zu speichern, die von anderen Feldern der Tabelle abhängig sind, sich also aus anderen Feldern berechnen (bzw. erschließen) lassen.

Folgendes Query müßte auch funktionieren, wenn Du Deinen (von kommen und gehen abhängigen) Zeitstempel weglässt:
Code:
SELECT 
user, 
SEC_TO_TIME(SUM( 
    UNIX_TIMESTAMP( gehen ) 
    - UNIX_TIMESTAMP( kommen ) ) )
    AS gesamtarbeitszeit
FROM zeitkarte
WHERE user LIKE 'dani'
AND MONTH( kommen ) =5
AND YEAR( kommen ) =2005
GROUP BY user
Das LIMIT ist übrigends überflüssig, wenn Du im WHERE auf einen einzelnen User beschränkst und nach diesem Wert gruppierst. Es wird nur einen Datensatz geben. Das GROUP BY wäre eigentlich auch überflüssig. Ich habe es jedoch drin gelassen, da das Query durch wegnehmen der User-Bedingung sofort auch alle User User ausspucken kann.

Für das Bilden einer Dauer mit Tagesangabe könntest Du folgendes probieren, wobei ich mir nicht sicher bin, ob es funktioniert. Gegebenenfalls könntest Du nochmal bei den Datums- und Zeitfunktionen vorbeischauen, die ich bereits verlinkt habe.
Code:
SELECT 
user, 
FROM_UNIXTIME(SUM( 
    UNIX_TIMESTAMP( gehen ) 
    - UNIX_TIMESTAMP( kommen ) ) ,
    '%e Tage %T')
    AS gesamtarbeitszeit
FROM zeitkarte
WHERE user LIKE 'dani'
AND MONTH( kommen ) =5
AND YEAR( kommen ) =2005
GROUP BY user

Gruß hpvw
 
Hallo,

und wieder bin ich ein kleines Stück schlauer geworden.

VIELEN VIELEN DANK!
 
Hallo,

ich habe mir deinen Hinweis auf gutes Datenbankdesign zu Herzen genommen und die ganze Geschichte umgestellt.
Jetzt tut sich mir aber wieder ein neues Problem auf.

Wenn ich nun über SQL folgendes abfrage:
Code:
SELECT id, user, kommen, mittaggehen, mittagkommen, gehen, (
(
UNIX_TIMESTAMP( gehen ) - UNIX_TIMESTAMP( kommen ) 
) - ( UNIX_TIMESTAMP( mittagkommen ) - UNIX_TIMESTAMP( mittaggehen ) ) 
) AS zeit
FROM `zeitkarte` 
WHERE user = 'dani'
LIMIT 0 , 30
dann bekomme ich auch schön alle Sekunden der jeweiligen Tage ausgerechnet.

Wenn ich aber nun Versuche mit der SUM()-Geschichte die Sekunden welche in "zeit" stehen zusammen zu zählen dann funkt das nicht.
Das ganze sieht dann so aus:
Code:
SELECT id, user, kommen, mittaggehen, mittagkommen, gehen, (
(
UNIX_TIMESTAMP( gehen ) - UNIX_TIMESTAMP( kommen ) 
) - ( UNIX_TIMESTAMP( mittagkommen ) - UNIX_TIMESTAMP( mittaggehen ) ) 
) AS zeit, SUM(zeit) AS zeitzusammen
FROM `zeitkarte` 
WHERE user = 'dani'
LIMIT 0 , 30
Ich bekomme dann die Fehlermeldung von SQL:

Unknown column 'zeit' in 'field list'

Was ich jetzt nicht verstehe - warum kommt diese Fehlermeldung - ich habe doch zuvor schon genau eben diese Spalte "zeit" definiert.

Wo liegt denn hier jetzt mein Problem?

Vielen Dank im Voraus!
 
Das liegt an MySQL.
Da das Ausrechnen der Werte nicht von MySQL garantiert werden kann, bevor diese tatsächlich in der entgültigen Ergebnistabelle landen (interne Query-Optimierung), gelten diese Felder in weiteren Selects als undefiniert. Erst weiter hinten, bei group by, order by oder irgendwo dahinten halt, sind sie bakannt.
Du musst also den ganzen Kram, den Du für zeit ausrechnest, danach nochmal in ein sum("der kram nochmal") schreiben und dann as zeitgesamt dahinter.

Gruß hpvw
 
Hallo,

hmmm - das verstehe ich jetzt nicht so ganz.

Ich hätte das mal versucht hier so ein zu bauen wie ich es verstanden habe - das funkt aber nicht.

Oder muss ich 2 Abfragen machen - und wenn ja wie geht das denn?

Vielen Dank für deine geduldige Hilfe!
 
Zurück