2017-02-12 4 views
1

Ich habe ein zu kompliziertes SQL-Problem (MySQL) für mich, und ich brauche Hilfe.MySQL Abfrage mit mindestens Zeilen als Spalten und Mittelwertbildung

Ich habe eine Tabelle mit Temperaturmesswerten. Diese Messwerte stammen von einer Anzahl von Sensoren, die an verschiedenen Orten platziert sind. Jede Lesung erfolgte zu einem Zeitstempel. Die Messungen werden alle zehn Minuten durchgeführt, und da die Messung sequentiell zwischen den Sensoren erfolgte, könnte zwischen den einzelnen Sensormessungen eine Sekunde liegen.

Zwei Sensoren lesen die Außentemperatur, was bedeutet, dass alle zehn Minuten zwei Messwerte (bei Position = 5 und Position = 6) die Außentemperatur reflektieren. Diese Sensoren sind auf der Nordseite und der Südseite des Gebäudes angebracht, was bedeutet, dass die niedrigste der zwei Messungen wahrscheinlich die genaueste ist, da die mit der höchsten derzeit durch Sonnenlicht ausgesetzt werden kann.

So eine Probe der Tabelle sieht wie diese

SELECT * FROM Temperatures 
WHERE timestamp > "2016-07-01 15:00" 
AND timestamp < "2016-07-01 15:40" 
AND (Location=5 OR Location=6) 
AND Site=3 
ORDER BY timestamp ASC 

(`ReadingID`, `Timestamp`, `Site`, `Location`, `Temperature`) 
(3921775, '2016-07-01 15:00:01', 3, 5, 18), 
(3921776, '2016-07-01 15:00:02', 3, 6, 17.5), 
(3921781, '2016-07-01 15:10:01', 3, 5, 18.6), 
(3921782, '2016-07-01 15:10:03', 3, 6, 17.9), 
(3921787, '2016-07-01 15:20:01', 3, 5, 18.4), 
(3921788, '2016-07-01 15:20:01', 3, 6, 22.7), 
(3921793, '2016-07-01 15:30:01', 3, 5, 19.4), 
(3921794, '2016-07-01 15:30:02', 3, 6, 29.2); 

Wie Sie die Zeitmarke mit einem zweiten zwischen location = 5 und location = 6, selbst wenn sie eine starke zeitliche Korrelation haben könnte unterscheiden sie sehen können. Um 15:00 und 15:10 hat Ort 6 die niedrigste Temperatur und 15:20 und 15:30 Ort 5 hat die niedrigste Temperatur. Die Lese-ID spielt hier keine Rolle.

Was ich will ist das Folgende: 1) Zeigen Sie das Minimum von Standort 5 und Standort 6 für jedes 10-Minuten-Intervall an. Wie würde diese Abfrage zum Beispiel für einen einzigen Tag aussehen? (Lassen Sie uns "2016.07.01 00:00" auf "2016.07.01 23.50" betrachten.

Ie. Die folgende

(`Timestamp (as 10 minute interval)`, `Location`, `Min of location 5 and 6`) 
'2016-07-01 00:00', <some data> 
... 
'2016-07-01 15:00', 6, 17.5 
'2016-07-01 15:10', 6, 17.9 
'2016-07-01 15:20', 5, 18.4 
'2016-07-01 15:30', 5, 19.4 
... 
'2016-07-02 23:50', <some data> 

2) Was wäre die durchschnittliche Außentemperatur für einen einzigen Tag in einem Intervall von einem Monat. Das ist die Durchschnittstemperatur von "2016-07-01 00:00" bis "2016-07-01 23:50", basierend auf der Minimaltemperatur von Ort 5 und Ort 6 für jeweils 10 Minuten. Wie würden Sie diese Abfrage schreiben?

In diesem letzteren Fall nehmen wir entweder an, dass alle Daten vorhanden sind, dh. dass es wirklich 144 Lesungen pro Tag gibt (das ist meistens der Fall) oder nehmen wir an, dass, wenn eine Lesung übersehen wird, sie den Durchschnitt nicht wirklich beeinflusst.

Eg. das folgende Ergebnis wird gesucht:

(`Date`, `Average based on min of location 5 and 6 for each 10 minute intervl`) 
'2017-07-01', 12.0 
'2017-07-02', 13.1 
'2017-07-03', 12.9 
etc. 
'2017-07-31', 17.7 

Mit freundlichen Grüßen Pål

Antwort

1

Für die erste Frage, die Sie eine Reihe von Datum-Stunden-Minute erzeugen können:

(select date_format(TimeStamp1, '%Y-%m-%d %H:%i') as TimeStamp, 
     min(Temperature) as Temperature 
from Temperatures 
group by date_format(TimeStamp1, '%Y-%m-%d %H:%i')) tserie 

und die Rückkehr des Ort, an dem Zeitstempel und Temperatur stimmt überein.

select tserie.TimeStamp, Location, tserie.Temperature 
from Temperatures 
    inner join (select date_format(TimeStamp1, '%Y-%m-%d %H:%i') as TimeStamp, 
         min(Temperature) as Temperature 
       from Temperatures 
       group by date_format(TimeStamp1, '%Y-%m-%d %H:%i')) tserie 
where date_format(TimeStamp1, '%Y-%m-%d %H:%i') = TimeStamp and tserie.Temperature = Temperatures.Temperature 
; 

Dies ist das Ergebnis:

+------------------+----------+-------------+ 
|  TimeStamp | Location | Temperature | 
+------------------+----------+-------------+ 
| 2016-07-01 15:00 |  6 | 17,50 | 
| 2016-07-01 15:10 |  6 | 17,90 | 
| 2016-07-01 15:20 |  5 | 18,40 | 
| 2016-07-01 15:30 |  5 | 19,40 | 
+------------------+----------+-------------+ 

Für den zweiten Teil, die gleiche Zeitreihe zwischen zwei Daten, die Berechnung der Durchschnittstemperatur mit:

select date_format(Tstamp2, '%Y-%m-%d') as Day, sum(Temperature)/count(*) as Avg 
from (select date_format(TimeStamp1, '%Y-%m-%d %H:%i') as Tstamp2, 
       min(Temperature) as Temperature 
     from Temperatures 
     where TimeStamp1 >= '2016-07-01' and TimeStamp1 < '2016-08-01' 
     group by date_format(TimeStamp1, '%Y-%m-%d %H:%i')) tserie 
group by date_format(Tstamp2, '%Y-%m-%d') 
; 

Das Ergebnis:

+------------+-----------+ 
|  Day | Avg | 
+------------+-----------+ 
| 2016-07-01 | 18,300000 | 
+------------+-----------+ 
| 2016-07-02 | 18,300000 | 
+------------+-----------+ 

Überprüfen Sie sie e: http://rextester.com/BXJW4041

+0

Vielen Dank. Ich bin etwas verwirrt, da Sie nicht dieselben Tabellen- und Spaltennamen verwenden wie ich. Die Tabelle heißt "Temperaturen" (und nicht Sensoren) und die Zeitstempelspalte heißt "Zeitstempel" (und nicht Tstamp, was eine unglückliche Wahl sein könnte). Wenn ich versuche, meine Namen zu tauschen, funktioniert es nicht. Und ich kann nicht sehen, was ich falsch mache. Würde es Ihnen etwas ausmachen, Ihre Abfrage so zu ändern, dass sie mit meinen Namen funktioniert? –

+0

Ok, ich habe einen neuen Rextester eingestellt, ich habe den Tabellennamen in Temperature und Tstamp Feld zu TimeStamp1 geändert (ich möchte nicht reservierte Wörter für Feldnamen verwenden). Versuchen Sie es hier: http://rexttester.com/BXJW4041 – McNets

+0

Und das ist wahrscheinlich klug, reservierte Namen nicht zu verwenden. Ich mag es auch nicht und weiß wirklich nicht, warum es so gelandet ist, weniger, dass es funktioniert ... Diese Abfrage scheint aber auch für den Server zu schwer zu sein, es gibt keine Antwort in 10 Sekunden. –

0

Sie können auch diese Abfrage verwenden, um die min von jeweils 10 Minuten

SELECT 
    DATE_FORMAT(t1.Timestamp, '%Y-%m-%d %H:%i') AS `Timestamp` 
    , IF(LEAST(t1.`Temperature`, t2.`Temperature`) = t1.`Temperature`, 
     IF(t1.`Temperature` = t2.`Temperature` , '5/6', 5), 6) AS Location 
    , LEAST(t1.`Temperature`, t2.`Temperature`) AS Temperature 
FROM Temperatures t1 
LEFT JOIN Temperatures t2 
ON 
    t2.Location = 6 
AND 
    t2.`TIMESTAMP` 
    BETWEEN 
     t1.`TIMESTAMP` - INTERVAL 5 SECOND 
    AND 
     t1.`TIMESTAMP` + INTERVAL 5 SECOND 
WHERE t1.Location = 5; 

Probe

Es wird zeigt Ihnen auch, wenn beide Sensoren die gleiche Temperatur haben.

mysql> select * from Temperatures; 
+-----------+---------------------+------+----------+-------------+ 
| ReadingID | Timestamp   | Site | Location | Temperature | 
+-----------+---------------------+------+----------+-------------+ 
| 3921775 | 2016-07-01 15:00:01 | 3 |  5 |  18.000 | 
| 3921776 | 2016-07-01 15:00:02 | 3 |  6 |  17.500 | 
| 3921781 | 2016-07-01 15:10:01 | 3 |  5 |  18.600 | 
| 3921782 | 2016-07-01 15:10:03 | 3 |  6 |  17.900 | 
| 3921787 | 2016-07-01 15:20:01 | 3 |  5 |  18.400 | 
| 3921788 | 2016-07-01 15:20:01 | 3 |  6 |  22.700 | 
| 3921793 | 2016-07-01 15:30:01 | 3 |  5 |  19.400 | 
| 3921794 | 2016-07-01 15:30:02 | 3 |  6 |  29.200 | 
| 3921795 | 2016-07-01 15:40:02 | 3 |  5 |  27.120 | 
| 3921796 | 2016-07-01 15:40:04 | 3 |  6 |  27.120 | 
+-----------+---------------------+------+----------+-------------+ 
10 rows in set (0,00 sec) 

mysql> SELECT 
    ->  DATE_FORMAT(t1.Timestamp, '%Y-%m-%d %H:%i') AS `Timestamp` 
    ->  , IF(LEAST(t1.`Temperature`, t2.`Temperature`) = t1.`Temperature`, 
    ->   IF(t1.`Temperature` = t2.`Temperature` , '5/6', 5), 6) AS Location 
    ->  , LEAST(t1.`Temperature`, t2.`Temperature`) AS Temperature 
    -> FROM Temperatures t1 
    -> LEFT JOIN Temperatures t2 
    -> ON 
    ->  t2.Location = 6 
    -> AND 
    ->  t2.`TIMESTAMP` 
    ->  BETWEEN 
    ->   t1.`TIMESTAMP` - INTERVAL 5 SECOND 
    ->  AND 
    ->   t1.`TIMESTAMP` + INTERVAL 5 SECOND 
    -> 
    -> WHERE t1.Location = 5; 
+------------------+----------+-------------+ 
| Timestamp  | Location | Temperature | 
+------------------+----------+-------------+ 
| 2016-07-01 15:00 | 6  |  17.500 | 
| 2016-07-01 15:10 | 6  |  17.900 | 
| 2016-07-01 15:20 | 5  |  18.400 | 
| 2016-07-01 15:30 | 5  |  19.400 | 
| 2016-07-01 15:40 | 5/6  |  27.120 | 
+------------------+----------+-------------+ 
5 rows in set (0,00 sec) 

mysql> 
+0

Diese Abfrage wird auf dem Server mit allen Daten in der Tabelle zu schwer. Ich denke, dass es zeitlich und örtlich begrenzt sein muss (Timestamp> = "2016-07-01 AND Timestamp <=" 2016-07-31 "UND Site = 3). Ich kann nicht lösen, wie man diese Beschränkung in die stellt Frage, könntest du bitte helfen? –

Verwandte Themen