# MySQL Max und Min Wert der letzten 24h



## gmhome (7. Februar 2018)

Hallo zusammen,

in folgende Tabelle:
CREATE DATABASE weather_station;
USE weather_station;
CREATE TABLE temperature (
 id int NOT NULL AUTO_INCREMENT,
 sender_id VARCHAR(20),
 datum DATETIME,
 temp FLOAT,
 humidity FLOAT,
 PRIMARY KEY(id)
);
wird alle 3 Minuten ein Temperaturwert geschrieben.
Ich möchte nun die Min und Max-Temperatur mit jeweils zugehörigem datum für den heutigen Tag auslesen, um am Ende eine Ausgabe von z.B. Max-Temp: 5°C um 12:35 Uhr machen zu können.

Mit folgender sql bekomme ich min und max aller gespeicherter Temperaturwerte:

$sql_max = "SELECT datum, temp FROM temperature WHERE temp=(select max(temp) FROM temperature)";
$sql_min = "SELECT datum, temp FROM temperature WHERE temp=(select min(temp) FROM temperature)";

leider funktioniert eine weitere Einschränkung mit "WHERE datum < '$heut'" nicht.

Hat irgendjemand eine Idee, wie ich die weitere Einschränkung auf einen festgelegten Datumsbereich hinbekomme?

Vielen Dank schon mal im Voraus!


----------



## Yaslaw (7. Februar 2018)

Der Where ist schon ein guter Ansatz.
1) der wehre muss ins Sub ins Subselect und ins Haubtselect
2) Von PHP (Unix-Timestamp) zu MySQL Datum muss konvertiert werden.
3) Wenn immer von Heute ausgegangen wird, dann brauchst du die PHP-Variable $heut gar nicht

Frage: Willst du die letzten 24 Stunden oder willst du heute ab Mitternacht?


----------



## gmhome (7. Februar 2018)

Vielen Dank für die schnelle Antwort, aber ich stehe etwas auf dem Schlauch.
Kannst Du mir vielleicht ein kurzes Beispiel posten?


----------



## gmhome (7. Februar 2018)

heute ab Mitternacht ist das Ziel. Sorry hatte die Frage übersehen


----------



## Yaslaw (7. Februar 2018)

Sobald du meine Frage beantwortet hast. Denn diese ist wichtig für die Berechnung


> Frage: Willst du die letzten 24 Stunden oder willst du heute ab Mitternacht?


Letzten 24Stunden -> Bedeutet jetzt (11:19) alles von 6.2.2018 11:19 bis 7.2.2018 11:19
Ab Mitternacht -> Bedeutet alles von 7.2.2018 00:00 bis 7.2.2018 23:59


----------



## gmhome (7. Februar 2018)

Ab Mitternacht -> Bedeutet alles von 7.2.2018 00:00 bis 7.2.2018 23:59


----------



## Yaslaw (7. Februar 2018)

Hier mein Test: http://sqlfiddle.com/#!9/0df222/5

```
select t.*
from
  temperature t
where
  t.temp in (
    select max(ma.temp)
    from temperature ma
    where date(ma.datum) = date(now())
    and date(ma.datum) = date(t.datum)
  )
;
```


----------



## gmhome (7. Februar 2018)

Hi Yaslaw,

vielen Dank nochmal. Da stelle ich doch mal wieder fest, dass ich offensichtlich keinen Plan von SQL habe...
Werde mal versuchen den code in php zu packen und auszulesen, aber das stellt mich schon vor einige Herausforderungen.

Muss ich "= Date(now())" jetzt noch durch "> $date_mitternacht" ersetzten?
kann ich mit $row = $output->fetch_assoc() dann als "$row[ma.temp]" und "$row[ma.datum]" auslesen?


----------



## Yaslaw (7. Februar 2018)

Nö. das geht genau so.
date() extrahiert das Datum aus einem Zeitstempel  (Datum + Uhrzeit)
now() Gibt den Aktuellen Zeitstempel zurück.

Somit vergleiche ich das Datum heute mit dem Datum aus der Messung. Das ganze ohne Uhrzeiten.

Da als Resultat der ganze Eintrag aus der Temperaturtabelle zurückgegeben wird, kannst du einfach diese Werte auslesen.
Das Feld Datum als Rückgabewert entspricht dem Feld Datum in der Tabelle. Also ein Zeitstempel

```
$temp = $row['temp'];
$date = $row['datum']
```

Schau dir auch den Test auf SQLFiddle an, den ich dafür erstellt habe: http://sqlfiddle.com/#!9/0df222/5


----------



## gmhome (7. Februar 2018)

Sorry für die dilettantische Frage...
Hatte es gerade durch Trial and Error auch herausgefunden, allerdings bekomme ich mit meiner Datenbasis mehr als eine Ausgabe wenn mehrere gleiche Temperaturwerte im Zeitraum vorhanden sind. Kann man das noch mit Order Desc Linie 1 einschränken?


----------



## Yaslaw (7. Februar 2018)

Kann man. Willst du den letzten oder den ersten Wert?
Für den letzten: http://sqlfiddle.com/#!9/0df222/8

```
select max(t.datum) as datum, t.temp
from
  temperature t
where
  t.temp in (
    select max(ma.temp)
    from temperature ma
    where date(ma.datum) = date(now())
    and date(ma.datum) = date(t.datum)
  )
group by t.temp
;
```


----------



## gmhome (7. Februar 2018)

Super! Der letzte macht erst mal Sinn und für jegliche weitere Anpassungen versuche ich mal wieder mein eigenes Hirn anzustrengen.

Vielen Dank!


----------



## gmhome (9. Februar 2018)

Hallo nochmal,

habe das Thema mit Deiner Hilfestellung wie nachfolgend aufgesetzt:

SELECT t.* 
FROM 
  temperature t 
WHERE 
  t.temp IN (
    SELECT MAX(ma.temp) 
    FROM temperature ma 
    WHERE date(ma.datum) = date(now()) 
    AND date(ma.datum) = date(t.datum)) 
GROUP BY t.temp

bzw.

SELECT MAX (t.datum) AS datum, t.temp 
FROM temperature t WHERE t.temp IN (
SELECT MAX(ma.temp) 
FROM temperature ma 
WHERE DATE(ma.datum) = DATE(now()) 
AND DATE(ma.datum) = DATE(t.datum)) 
GROUP BY t.temp

Es liefert auch genau das gewünschte Ergebnis, allerdings dauert die Abfrage der Datenbank mehrere Sekunden. Ist da noch ein mir nicht ersichtlicher Fehler im SQL code, oder ist die Abfrage tatsächlich so komplex, dass sie umfangreichere Server Ressourcen benötigt?


----------



## Kalito (10. Februar 2018)

naja,


die sql ansich sieht ganz ok aus. Je nach Datenmenge und der darunterliegende Hardware kann das schon mehrere Sekunden dauern. Eventuell hilft es, wenn du ein Index setzt


----------

