brauch Hilfe bei MySQL-Statement
Matze
- datenbank
Hallo und guten Morgen!
Ich habe eine Tabelle mit 1440 Datensätzen.
Jeder hat einen Zeitstempel.
Jede Minute, 24 Stunden ein Eintrag.
Jetzt möchte ich für jede Stunde der letzten 24 Stunden den höchsten Wert einer Spalte ermitteln.
Das Datum liegt in der Form 2008-01-20 01:30 vor.
Die Daten der Spalte "Daten" liegen in der Form 0.000, 2.256, 8.557 ... vor.
Das ganze dient statistischen Zwecken.
Mein Gedankengang ist jetzt eine Schleife zu schreiben die 24 mal durchlaufen wird, das aktuelle Datum "n" zu ermitteln, davon den Schleifendurchlauf abziehn.
Dann den höchsten Wert der Datensätze von n bis n+1 ermittelt und in ein Array schreiben.
<?PHP
$arr = array();
for($i=24; $i > 0; $i--){
$starttime = date("Y-m-d H:i", time()-60*60*$i);
$sql = "SELECT * FROM table WHERE Datum > '".$starttime."' ORDER BY Daten DESC LIMIT 1";
$query = mysql_query($sql);
$fetch = mysql_fetch_assoc($query);
array_push($arr, $fetch['Daten']);
}
echo '<pre>';
print_r($arr);
echo '</pre>';
?>
Das Ganze erscheint mir aber irgendwie umständlich.
Geht das auch in einem Statement und ohne Schleife?
Danke und Grüße, Matze
Hi,
Jetzt möchte ich für jede Stunde der letzten 24 Stunden den höchsten Wert einer Spalte ermitteln.
Das Datum liegt in der Form 2008-01-20 01:30 vor.
Also eines der MySQL-Datumsformate als Spaltentyp?
Mein Gedankengang ist jetzt eine Schleife zu schreiben die 24 mal durchlaufen wird, das aktuelle Datum "n" zu ermitteln, davon den Schleifendurchlauf abziehn.
Abfragen in Schleifen abzufeuern, ist (fast) *nie* eine gute Idee.
Informiere dich ueber Gruppierung und Aggregatfunktionen.
MfG ChrisB
Hallo Chris!
Jetzt möchte ich für jede Stunde der letzten 24 Stunden den höchsten Wert einer Spalte ermitteln.
Das Datum liegt in der Form 2008-01-20 01:30 vor.Also eines der MySQL-Datumsformate als Spaltentyp?
Ja. Mit Sekunden noch natürlich. Die hab ich mal unterschlagen.
Abfragen in Schleifen abzufeuern, ist (fast) *nie* eine gute Idee.
Ja das ist halt das Problem das ich hab ;)
Informiere dich ueber Gruppierung und Aggregatfunktionen.
Oha... mal sehn ob ich was finde...
Danke und Grüße, Matze
Hallo Chris!
Informiere dich ueber Gruppierung und Aggregatfunktionen.
Ich versteh das leider überhaupt nicht. Mir ist nicht ganz klar wo, wie und was ich gruppieren soll.
Ich komme nicht mehr über den Gedanken hinaus, dass ich zunächst irgendwie die Datensätze der letzten 24h greifen muss. Aber ich hab keine Idee, wie ich die Daten der einzelnen Stunden ohne Schleife vergleichen kann bzw. nur die relevanten heraus krieg.
Hab ein Brett vorm Kopf.
Kannst du mir vielleicht ein Beispiel geben und versuchen es mir zu erklären?
Danke und Grüße, Matze
Hi,
Ich versteh das leider überhaupt nicht. Mir ist nicht ganz klar wo, wie und was ich gruppieren soll.
Natuerlich gruppierst du ueber das, wovon du auch den Maximalwert haben willst - also in diesem Falle die Datumsangabe bis "herunter" zur vollen Stunde.
Dazu musst du das Datum natuerlich entsprechend umformatieren.
Ich komme nicht mehr über den Gedanken hinaus, dass ich zunächst irgendwie die Datensätze der letzten 24h greifen muss.
Das kannst du ja zusaetzlich ueber die WHERE-Klausel machen, wenn dich nur Daten aus diesem Zeitraum interessieren.
MfG ChrisB
Hallo Chris!
Natuerlich gruppierst du ueber das, wovon du auch den Maximalwert haben willst - also in diesem Falle die Datumsangabe bis "herunter" zur vollen Stunde.
Dazu musst du das Datum natuerlich entsprechend umformatieren.
Warum und in was umformatieren?
Und ich hab immernoch nicht die geringste Ahnung wie ich das aufschreiben müsste :(
Also 3 Sachen in einem Statement? Die Abfrage der letzten 24 Stunden, der Stunden und dann noch den Maximalwert davon?
GROUP BY max(Daten)? Aber wieso muss ich das Datum ändern?
Ich versteh es immernoch nicht ôO
Danke und Grüße, Matze
Hi,
Natuerlich gruppierst du ueber das, wovon du auch den Maximalwert haben willst - also in diesem Falle die Datumsangabe bis "herunter" zur vollen Stunde.
Dazu musst du das Datum natuerlich entsprechend umformatieren.Warum und in was umformatieren?
Wenn du nach dem vollstaendigen Datumswert (inkl. Sekunden) Gruppieren wuerdest, bekaemst du wohl kaum ein sinnvolles Ergebnis, weil dann jede Sekunde eine eigene "Gruppe" bilden wuerde.
Und ich hab immernoch nicht die geringste Ahnung wie ich das aufschreiben müsste :(
Also 3 Sachen in einem Statement?
SELECT-Statements koennen die unterschiedlichsten "Sachen" enthalten.
Ich versteh es immernoch nicht ôO
Dann mach dir das mit der Gruppierung doch vielleicht erst mal an einem einfacheren Beispiel klar, als an einem Teil eines Datumswertes.
MfG ChrisB
Hallo Chris!
Dazu musst du das Datum natuerlich entsprechend umformatieren.
Warum und in was umformatieren?
Wenn du nach dem vollstaendigen Datumswert (inkl. Sekunden) Gruppieren wuerdest, bekaemst du wohl kaum ein sinnvolles Ergebnis, weil dann jede Sekunde eine eigene "Gruppe" bilden wuerde.
Das leuchtet mir ein.
Ich versteh es immernoch nicht ôO
Dann mach dir das mit der Gruppierung doch vielleicht erst mal an einem einfacheren Beispiel klar, als an einem Teil eines Datumswertes.
Ja ich hab aber kein kleines Beispiel. Ich kann nicht lesen lernen ohne Buch.
Ich würde ja gern erstmal als Beispiel die "Daten"-Spalte nach irgendwas gruppieren.
Z.B. 0.000 bis 0.999, 1.000 bis 1.999 uswusf.
Die Werte können 0.000 bis 9.999 sein.
Nur wozu, also was mach ich mit so einer Gruppe anschließend?
Mir fehlt aber komplett der Ansatz :(
Ich versteh nicht wie ich mit der Gruppe umgehen soll oder wie ich sie erstelle. Das Handbuch hilft mir leider auch nicht weiter. Zu kompliziert beschrieben.
Danke, Matze
Hi,
Ja ich hab aber kein kleines Beispiel.
Dann benutze deine Phantasie, und denk dir eins aus.
Z.B. mal nur ein paar Datensaetze mit einem Kennzeichen (1, 2, 3, jeweils mehrfach vorkommend) in einer Spalte, und irgendwelchen Zahlenwerten in einer zweiten.
Dann gruppierst du mal nach dem Kennzeichen, und laesst dir den Maximalwert je Gruppe ermitteln.
Ich kann nicht lesen lernen ohne Buch.
Du koenntest es ja mal mit Lesen *im* Buch versuchen - das MySQL-Handbuch hat auch zu GROUP BY Beispiele. (bspw. unter http://dev.mysql.com/doc/refman/5.1/en/group-by-modifiers.html)
Ich würde ja gern erstmal als Beispiel die "Daten"-Spalte nach irgendwas gruppieren.
Z.B. 0.000 bis 0.999, 1.000 bis 1.999 uswusf.
Die Werte können 0.000 bis 9.999 sein.
Du koennest z.B. erst mal das Datum nach Jahr oder Monat, oder nach beidem Gruppieren lassen.
Nur wozu, also was mach ich mit so einer Gruppe anschließend?
Na bspw. den Maximalwert des Inhaltes einer Spalte ueber alle Datensaetze in einer "Gruppe" ermitteln - also eigentlich das, was du doch von Anfang an wolltest ...
MfG ChrisB
Hallo Chris!
Du koennest z.B. erst mal das Datum nach Jahr oder Monat, oder nach beidem Gruppieren lassen.
Wie kann ich denn das Jahr oder den Monat eingrenzen?
Grüße, Matze
Hi,
Du koennest z.B. erst mal das Datum nach Jahr oder Monat, oder nach beidem Gruppieren lassen.
Wie kann ich denn das Jahr oder den Monat eingrenzen?
In dem du es bspw. mittels geeigneter Datumsfunktionen aus dem Datumswert extrahierst, und im GROUP BY verwendest.
MfG ChrisB
Hallo!
Wenn ich versuche "SELECT Daten FROM table GROUP BY Daten" kommt ein Array mit dem letzten Datensatz raus. Ich habe aber ein Array mit allen verschiedenen Datensätzen erwartet.
Grüße, Matze
Hi,
Wenn ich versuche "SELECT Daten FROM table GROUP BY Daten" kommt ein Array mit dem letzten Datensatz raus.
Dann hat also die Spalte Daten in allen Datensaetzen den selben Wert?
(Und es kommt nicht "der letzte" heraus, sondern ein zufaelliger.)
Ich habe aber ein Array mit allen verschiedenen Datensätzen erwartet.
Wie viele Datensaetze du erhaeltst, haengt davon ab, wie viele unterschiedliche Werte die Kombination, ueber die du gruppierst, enthaelt.
MfG ChrisB
Hi,
Wenn ich versuche "SELECT Daten FROM table GROUP BY Daten" kommt ein Array mit dem letzten Datensatz raus.
Dann hat also die Spalte Daten in allen Datensaetzen den selben Wert?
Nein, ich hatte einen Fehler bei der Ausgabe. Sorry.
Ok, ich bekomme jetzt also mein Array mit den jeweiligen Werten. Jeder Wert nur 1 mal.
Jetzt muss ich es so schreiben, dass die letzten 365 Tage gruppiert werden.
Note:
Nicht wundern weil ich jetzt zu 365 Tagen springe, aber da hab ich mehr Werte die ich bearbeiten kann. In den letzten 24h ist nur 1 Wert gespeichert.
Wie du gesagt hast, ergibt mein Datum in dem Fall wenig Sinn, weil ich so nach Sekunden gruppieren würde.
Also versuch ich mal Tage zu gruppieren...
"SELECT Daten, Datum FROM table GROUP BY DATE_FORMAT(Datum, '%Y%m%d')"
Funktioniert soweit auch bestens. Langsam bin ich wieder motoviert :)
Jetzt fehlt also nur noch die Abfrage nach dem Maximalwert und die Zeiteingrenzung, richtig?
$starttime = date("Y-m-d H:i", time()-60*60*24*365);
$sql = "SELECT MAX(Daten) FROM table WHERE Datum > '".$starttime."' GROUP BY DATE_FORMAT(Datum, '%Y%m%d') ORDER BY Datum DESC";
$query = mysql_query($sql);
while($fetch = mysql_fetch_assoc($query)){
echo '<pre>';
print_r($fetch);
echo '</pre>';
}
Ich bin grad dabei die Ausgabe zu überprüfen, aber es scheint zu funktionieren :)
Bitte sag doch fall du noch einen Verbesserungsvorschlag hast.
Herzlichen Dank!!
Grüße, Matze
echo $begrüßung;
Bitte sag doch fall du noch einen Verbesserungsvorschlag hast.
$sql = "SELECT MAX(Daten) FROM table WHERE Datum > '".$starttime."' GROUP BY DATE_FORMAT(Datum, '%Y%m%d') ORDER BY Datum DESC";
Es gibt die Funktion EXTRACT()
$query = mysql_query($sql);
while($fetch = mysql_fetch_assoc($query)){
Fehlerbehandlung nicht unterschlagen! Wenn bei mysql_query() ein Fehler auftrat, ist das Rückgabeergebnis kein gültiger Wert für die Fetch-Funktionen. Es ist in dem Fall auch nicht sinnvoll, das Programm weiterzuführen als ob nichts war.
echo "$verabschiedung $name";
Hallo dedlfix!
Es gibt die Funktion EXTRACT()
Danke, aber durch die von Vinzenz vorgeschlagene Änderung erübrigt sich das oder?
Fehlerbehandlung nicht unterschlagen! (...)
Hab ich nur im Post unterschlagen, bei mir ist sie natürlich eingebaut.
Grüße, Matze
echo $begrüßung;
Es gibt die Funktion EXTRACT()
Danke, aber durch die von Vinzenz vorgeschlagene Änderung erübrigt sich das oder?
Nicht unbedingt. Er geht mit DATE_FORMAT() den Weg über eine Stringbildung. EXTRACT() ermittelt Teile des Datums, ohne sie in die durch den Formatstring angegebene Form zu bringen. Letztlich wird sich das in der Ausführung nicht viel nehmen, vermute ich mal, aber DATE_FORMAT() halte ich an der Stelle für missbraucht. EXTRACT() nähme ich aber nur für Monate in Verbindung mit einem Jahr. Für den Datumsteil aus einem DATETIME-Wert gibt es DATE() und für das Jahr YEAR().
echo "$verabschiedung $name";
Hallo,
Funktioniert soweit auch bestens. Langsam bin ich wieder motoviert :)
Jetzt fehlt also nur noch die Abfrage nach dem Maximalwert und die Zeiteingrenzung, richtig?
wozu benötigst Du folgende PHP-Anweisung? Weg damit!
$starttime = date("Y-m-d H:i", time()-606024*365);
$sql = "SELECT MAX(Daten) FROM table WHERE Datum > '".$starttime."' GROUP BY DATE_FORMAT(Datum, '%Y%m%d') ORDER BY Datum DESC";
Ich sehe einfach keine Notwendigkeit dafür, nimm beispielsweise:
[code lang=sql]
SELECT
MAX(Daten)
FROM
tabelle
WHERE
Datum > [link:http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_now@title=NOW()] - [link:http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_date-add@title=INTERVAL 24 HOUR]
GROUP BY
DATE_FORMAT(Datum, '%Y%m%d')
ORDER BY
Datum DESC
> Bitte sag doch fall du noch einen Verbesserungsvorschlag hast.
Rechne nie in Sekunden, wenn Du Stunden meinst.
Rechne erst recht nie in Sekunden, wenn Du Tage meinst :-)
Bau keine Zeichenkette zusammen, wenn es nicht nötig ist.
Bist Du Dir sicher, dass Du zwei verschiedene Werte haben willst? Derzeit bekommst Du in den meisten Fällen zwei Werte. Ermittelst Du aus diesen wiederum den größeren? Wenn ja, dann gruppierst Du falsch :-)
Freundliche Grüße
Vinzenz
Hallo Vinzenz!
Danke für die Verbesserung!
Bist Du Dir sicher, dass Du zwei verschiedene Werte haben willst? Derzeit bekommst Du in den meisten Fällen zwei Werte. Ermittelst Du aus diesen wiederum den größeren? Wenn ja, dann gruppierst Du falsch :-)
Also ich habe schon gemerkt, dass ich 25 Datensätze, nicht 24 bekomme.
Ich dachte aber immer, nicht manchmal.
In meinem Code hatte ich deshalb bei 24h jetzt so geschrieben. Also 23
$starttime = date("Y-m-d H", time()-60*60*23);
Jetzt mit der von dir vorgeschlagenen Änderung bekomme ich auch wieder 25 statt 24 Datensätze. Wo ist denn da mein Denkfehler?
Danke und Grüße, Matze
mh... mit LIMIT 24 stimmts wieder. Die angebrochene Stunde war wohl zu viel. :)
Grüße, Matze
Mahlzeit Matze,
Hab ein Brett vorm Kopf.
Macht nix, gibt genügend Kneifzangen und Sägen hier im Forum ... ;-)
Kannst du mir vielleicht ein Beispiel geben und versuchen es mir zu erklären?
Könntest Du dann bitte erstmal einen Ausschnitt aus der Tabelle, wie sie existiert und die von Dir gewünschte Ergebnismenge posten? So könnten sich potentielle Helfe ungefähr vorstellen, was vorhanden ist und was Du wünschst, und deshalb erheblich zielführendere Antworten und Vorschläge geben.
MfG,
EKKi
PS: Bei einem reinen Datenbank- bzw. -abfrageproblem ist PHP-Code nicht nur absolut irrelevant, sondern auch in keinster Wiese hilfreich.
Hey EKKI!
Hab ein Brett vorm Kopf.
Macht nix, gibt genügend Kneifzangen und Sägen hier im Forum ... ;-)
Ja manchmal gehts nicht anders^^
PS: Bei einem reinen Datenbank- bzw. -abfrageproblem ist PHP-Code nicht nur absolut irrelevant, sondern auch in keinster Wiese hilfreich.
Es ging mir darum zu zeigen, dass ich eine Lösung hatte und warum ich mit der unzufrieden bin.
Ich hab deinen Post erst zu spät gelesen und ein paar Datensätze hatte ich später gepostet. Ich dachte auch, ich hab die 2 wichtigen Spalten der Tabelle ausreichend beschrieben ;)
Mein Problem ist erstmal gelöst.
Grüße, Matze