0

I recorded values from temperature and humidity sensors, like that :

mysql> SELECT date,valeur FROM temperature WHERE date >= NOW() - INTERVAL 2 HOUR;
+---------------------+--------+
| date                | valeur |
+---------------------+--------+
| 2013-09-26 11:30:40 |   25.2 |
| 2013-09-26 11:33:19 |   25.4 |
| 2013-09-26 11:34:12 |   25.5 |
| 2013-09-26 11:38:37 |   25.4 |
| 2013-09-26 11:39:30 |   25.4 |
| 2013-09-26 11:40:23 |   25.4 |
| 2013-09-26 11:43:02 |   25.4 |
| 2013-09-26 11:45:41 |   25.3 |
| 2013-09-26 11:47:33 |   25.3 |
| 2013-09-26 11:51:07 |   25.4 |
| 2013-09-26 11:51:52 |   25.3 |
| 2013-09-26 11:53:38 |   25.4 |
...
| 2013-09-26 12:26:20 |   25.5 |
| 2013-09-26 12:27:12 |   25.5 |
| 2013-09-26 12:32:30 |   25.4 |
| 2013-09-26 12:35:09 |   25.5 |
| 2013-09-26 12:36:02 |   25.5 |
| 2013-09-26 12:37:50 |   25.6 |
| 2013-09-26 12:40:27 |   25.6 |
| 2013-09-26 12:49:18 |   25.6 |
| 2013-09-26 12:52:54 |   25.6 |
...
| 2013-09-26 13:16:40 |   25.5 |
| 2013-09-26 13:17:33 |   25.6 |
| 2013-09-26 13:22:05 |   25.5 |
| 2013-09-26 13:22:51 |   25.5 |
| 2013-09-26 13:23:44 |   25.5 |
| 2013-09-26 13:24:37 |   25.5 |
| 2013-09-26 13:25:30 |   25.5 |
| 2013-09-26 13:28:09 |   25.6 |
+---------------------+--------+

mysql> SELECT date,valeur FROM humidite WHERE date >= NOW() - INTERVAL 2 HOUR;
+---------------------+--------+
| date                | valeur |
+---------------------+--------+
| 2013-09-26 11:30:40 |     78 |
| 2013-09-26 11:33:19 |     78 |
| 2013-09-26 11:34:12 |     78 |
| 2013-09-26 11:38:37 |     78 |
| 2013-09-26 11:39:30 |     78 |
| 2013-09-26 11:40:23 |     78 |
| 2013-09-26 11:43:02 |     79 |
| 2013-09-26 11:45:41 |     78 |
| 2013-09-26 11:47:33 |     78 |
| 2013-09-26 11:51:07 |     79 |
| 2013-09-26 11:51:52 |     79 |
| 2013-09-26 11:53:38 |     79 |
...
| 2013-09-26 12:22:48 |     78 |
| 2013-09-26 12:26:20 |     78 |
| 2013-09-26 12:27:12 |     78 |
| 2013-09-26 12:32:30 |     77 |
| 2013-09-26 12:35:09 |     77 |
| 2013-09-26 12:36:02 |     77 |
| 2013-09-26 12:37:50 |     78 |
| 2013-09-26 12:40:27 |     77 |
| 2013-09-26 12:43:06 |     78 |
| 2013-09-26 13:22:05 |     78 |
...
| 2013-09-26 13:22:51 |     78 |
| 2013-09-26 13:23:44 |     78 |
| 2013-09-26 13:24:37 |     78 |
| 2013-09-26 13:25:30 |     78 |
| 2013-09-26 13:28:09 |     78 |
+---------------------+--------+

From this post I used this mysql command to join the two tables and get one value for each hour since 24 hours :

SELECT DATE_FORMAT(timeTable.minuteTime, '%Y-%m-%d %k:%i') date,
T2.valeur temp,
P2.valeur hum
FROM
(
    SELECT minuteTime.minuteTime minuteTime,
    ( SELECT MAX(date) FROM temperature WHERE date <= minuteTime.minuteTime AND date >= NOW() - INTERVAL 1 DAY) tempTime,
    ( SELECT MAX(date) FROM humidite WHERE date <= minuteTime.minuteTime AND date >= NOW() - INTERVAL 1 DAY) humTime
    FROM
    (
        SELECT DATE(date) + INTERVAL (HOUR(date) DIV 1 * 1) HOUR minuteTime
        FROM humidite
        WHERE date >= NOW() - INTERVAL 1 DAY AND date <= NOW()
        UNION SELECT DATE(date) + INTERVAL (HOUR(date) DIV 1 * 1) HOUR
        FROM temperature
        WHERE date >= NOW() - INTERVAL 1 DAY AND date <= NOW()
        GROUP BY 1
    ) minuteTime
) timeTable
LEFT JOIN temperature T2 ON T2.date = timeTable.tempTime
LEFT JOIN humidite P2 ON P2.date = timeTable.humTime
ORDER BY minuteTime ASC;

It works well, but I don't really understand how the value is chosen (random in the interval ?). I would prefer an average for each hour instead :

+------------------+------+------+
| date             | temp | hum  |
+------------------+------+------+
| 2013-09-25 13:00 | NULL | NULL |
| 2013-09-25 14:00 | 25.1 |   80 |
| 2013-09-25 15:00 | 25.3 |   78 |
| 2013-09-25 16:00 | 25.6 |   75 |
| 2013-09-25 17:00 | 25.5 |   75 |
| 2013-09-25 18:00 | 25.0 |   78 |
| 2013-09-25 19:00 | 24.2 |   80 |
| 2013-09-25 20:00 | 23.9 |   84 |
| 2013-09-25 21:00 | 23.9 |   84 |
| 2013-09-25 22:00 | 24.1 |   83 |
| 2013-09-25 23:00 | 24.1 |   83 |
| 2013-09-26 0:00  | 24.0 |   82 |
| 2013-09-26 1:00  | 23.9 |   84 |
| 2013-09-26 2:00  | 23.7 |   86 |
| 2013-09-26 3:00  | 23.7 |   84 |
| 2013-09-26 4:00  | 23.7 |   85 |
| 2013-09-26 5:00  | 23.4 |   85 |
| 2013-09-26 6:00  | 23.6 |   85 |
| 2013-09-26 7:00  | 23.7 |   85 |
| 2013-09-26 8:00  | 24.0 |   84 |
| 2013-09-26 9:00  | 24.4 |   82 |
| 2013-09-26 10:00 | 24.6 |   81 |
| 2013-09-26 11:00 | 25.2 |   79 |
| 2013-09-26 12:00 | 25.4 |   79 |
| 2013-09-26 13:00 | 25.6 |   78 |
+------------------+------+------+
25 rows in set (1.11 sec)

Do you know how to put the AVG() in this code ?

Bonus question : I changed the code to get one value for each hour. Do you know how to get 1 value every 30 min ?

Thanks for your help

2 Answers 2

0

Try this:

select FROM_UNIXTIME( TRUNCATE(UNIX_TIMESTAMP(timeTable.minuteTime) / 1800,0)*1800) as halfHour,
avg(T2.valeur) as avgTemp,
avg(P2.valeur) as avgHum
FROM
(
    SELECT minuteTime.minuteTime minuteTime,
    ( SELECT MAX(date) FROM temperature WHERE date <= minuteTime.minuteTime AND date >= NOW() - INTERVAL 1 DAY) tempTime,
    ( SELECT MAX(date) FROM humidite WHERE date <= minuteTime.minuteTime AND date >= NOW() - INTERVAL 1 DAY) humTime
    FROM
    (
        SELECT DATE(date) + INTERVAL (HOUR(date) DIV 1 * 1) HOUR minuteTime
        FROM humidite
        WHERE date >= NOW() - INTERVAL 1 DAY AND date <= NOW()
        UNION SELECT DATE(date) + INTERVAL (HOUR(date) DIV 1 * 1) HOUR
        FROM temperature
        WHERE date >= NOW() - INTERVAL 1 DAY AND date <= NOW()
        GROUP BY 1
    ) minuteTime
) timeTable
LEFT JOIN temperature T2 ON T2.date = timeTable.tempTime
LEFT JOIN humidite P2 ON P2.date = timeTable.humTime
group by FROM_UNIXTIME( TRUNCATE(UNIX_TIMESTAMP(timeTable.minuteTime) / 1800,0)*1800)
ORDER BY 1 ASC;
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Tom Mac for your reply. The average seems to work well, but output is still one line by hour and not every 30 minutes. Maybe I need to change the DATE(date) + INTERVAL HOUR(date) HOUR minuteTime by something else ?
I tested again, and the average gives strange values : temperatures are always something as ab.c0000 and humidity always de.0. It seems too "rounded" to be a real average ! An idea ?
0

Thanks to Tom Mac and other usefull posts on this site, I ended up with this code :

select DATE_FORMAT(timeTable.minuteTime, '%Y-%m-%d %k:%i') as date,
  (UNIX_TIMESTAMP(timeTable.minuteTime)*1000) AS dte,
  T2.valeur as avgTemp,
  P2.valeur as avgHum
  FROM ( 
    SELECT minuteTime.minuteTime minuteTime,      
    ( SELECT MAX(date) FROM temperature WHERE date <= minuteTime.minuteTime AND
     date >= NOW() - INTERVAL 170 HOUR) tempTime,
    ( SELECT MAX(date) FROM humidite WHERE date <= minuteTime.minuteTime AND
     date >= NOW() - INTERVAL 170 HOUR) humTime
    FROM( 
     SELECT date + INTERVAL 59 - SECOND( date ) SECOND minuteTime
     FROM humidite
     WHERE date >= NOW() - INTERVAL 7 DAY AND date <= NOW()
     UNION SELECT date + INTERVAL 59 - SECOND( date ) SECOND
     FROM temperature
     WHERE date >= NOW() - INTERVAL 7 DAY AND date <= NOW()
     GROUP BY 1
    ) minuteTime
  ) timeTable
  LEFT JOIN temperature T2 ON T2.date = timeTable.tempTime
  LEFT JOIN humidite P2 ON P2.date = timeTable.humTime
  group by FROM_UNIXTIME( TRUNCATE(UNIX_TIMESTAMP(timeTable.minuteTime) / 1800,0)*1800)
  ORDER BY minuteTime ASC;

Now I'm able to compute dew points for each hour using a dedicated php code that I put here (for information) :

function calculateDewPoint($temperature, $humidity) {
    $a = 17.27 ;
    $b = 237.7 ;

    $c = (($a * $temperature) / ($b + $temperature) ) + Log($humidity/100) ;
    $d = (($b * $c)/($a - $c));
    return number_format($d, 1);
}

Next update would be to put this code directly in mysql request..

Best regards

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.