So, I have got following data in a MySQL table:
mysql> SELECT * FROM reading LIMIT 0,10;
+----+---------------------+-------+-------------+
| id | date | power | temperature |
+----+---------------------+-------+-------------+
| 1 | 2011-02-15 21:58:41 | 124 | 22 |
| 2 | 2011-02-15 21:58:47 | 123 | 22 |
| 3 | 2011-02-15 21:58:53 | 124 | 22 |
| 4 | 2011-02-15 21:58:59 | 686 | 22 |
| 5 | 2011-02-15 21:59:05 | 126 | 22 |
| 6 | 2011-02-15 21:59:11 | 123 | 22 |
| 7 | 2011-02-15 21:59:17 | 122 | 22 |
| 8 | 2011-02-15 21:59:47 | 122 | 22 |
| 9 | 2011-02-15 21:59:59 | 122 | 22 |
| 10 | 2011-02-15 22:00:29 | 123 | 22 |
+----+---------------------+-------+-------------+
10 rows in set (0.00 sec)
(it is not a secret these are readings from Current Cost device)
Now, I have been battling SQL for few hours to get a average power amount over a 15 minutes period. The closest I could get is:
SELECT
CONCAT(
DATE(date), ' ',
HOUR(date), ':',
CASE
WHEN MINUTE(date) BETWEEN 0 AND 14 THEN '00'
WHEN MINUTE(date) BETWEEN 15 AND 29 THEN '15'
WHEN MINUTE(date) BETWEEN 30 AND 44 THEN '30'
WHEN MINUTE(date) BETWEEN 45 AND 59 THEN '45'
END
) AS date,
ROUND(AVG(power),1)
FROM reading
WHERE date > '2011-02-20' AND date < '2011-02-21'
GROUP BY date;
Which gives me result as following:
mysql> SELECT
-> CONCAT(
-> DATE(date), ' ',
-> HOUR(date), ':',
-> CASE
-> WHEN MINUTE(date) BETWEEN 0 AND 14 THEN '00'
-> WHEN MINUTE(date) BETWEEN 15 AND 29 THEN '15'
-> WHEN MINUTE(date) BETWEEN 30 AND 44 THEN '30'
-> WHEN MINUTE(date) BETWEEN 45 AND 59 THEN '45'
-> END
-> ) AS date,
-> ROUND(AVG(power),1)
-> FROM reading
-> WHERE date > '2011-02-20' AND date < '2011-02-21'
-> GROUP BY date LIMIT 0,10;
+-----------------+---------------------+
| date | ROUND(AVG(power),1) |
+-----------------+---------------------+
| 2011-02-20 0:00 | 320.0 |
| 2011-02-20 0:00 | 319.0 |
| 2011-02-20 0:00 | 317.0 |
| 2011-02-20 0:00 | 313.0 |
| 2011-02-20 0:00 | 315.0 |
| 2011-02-20 0:00 | 315.0 |
| 2011-02-20 0:00 | 320.0 |
| 2011-02-20 0:00 | 315.0 |
| 2011-02-20 0:00 | 315.0 |
| 2011-02-20 0:00 | 313.0 |
[...]
| 2011-02-20 0:45 | 316.0 |
| 2011-02-20 0:45 | 311.0 |
| 2011-02-20 0:45 | 310.0 |
| 2011-02-20 0:45 | 317.0 |
| 2011-02-20 0:45 | 311.0 |
| 2011-02-20 0:45 | 312.0 |
| 2011-02-20 0:45 | 318.0 |
| 2011-02-20 0:45 | 315.0 |
| 2011-02-20 0:45 | 313.0 |
| 2011-02-20 0:45 | 316.0 |
| 2011-02-20 0:45 | 311.0 |
| 2011-02-20 0:45 | 312.0 |
| 2011-02-20 0:45 | 319.0 |
| 2011-02-20 0:45 | 312.0 |
[...]
| 2011-02-20 4:00 | 95.0 |
| 2011-02-20 4:15 | 95.0 |
| 2011-02-20 4:15 | 95.0 |
| 2011-02-20 4:15 | 94.0 |
| 2011-02-20 4:15 | 94.0 |
| 2011-02-20 4:15 | 94.0 |
| 2011-02-20 4:15 | 94.0 |
| 2011-02-20 4:15 | 94.0 |
| 2011-02-20 4:15 | 94.0 |
| 2011-02-20 4:15 | 96.0 |
| 2011-02-20 4:15 | 93.0 |
| 2011-02-20 4:15 | 94.0 |
| 2011-02-20 4:15 | 93.0 |
| 2011-02-20 4:15 | 93.0 |
+-----------------+---------------------+
10 rows in set, 1 warning (0.20 sec)
Which is still quite far away from what I am trying to get. It seems like I am very close to what I need, just something to DISTINCT the date field and get averages from all equal dates fields, but I just can’t get the correct SQL.
The result I am aiming for is something along lines:
| 2011-02-20 4:00 | 94.0 |
| 2011-02-20 4:15 | 194.3 |
| 2011-02-20 4:30 | 197.4 |
| 2011-02-20 4:45 | 145.3 |
| 2011-02-20 5:00 | 94.0 |
| 2011-02-20 5:15 | 96.0 |
| 2011-02-20 5:30 | 93.0 |
| 2011-02-20 5:45 | 94.0 |
Any help or hints much appreciated.
MySQL is getting confused because you’ve aliased your
CONCAT()output to the same name as an existing column, soGROUP BY dateis grouping by the table’s date field, not your rounded-to-the-nearest-15-minutes date.You’ll need to change your query to something like
Also, instead of
HOUR()I would useDATE_FORMAT()in order to zeropad the hours, otherwise “5” (5AM) comes after “17” (5PM).CONCAT(DATE_FORMAT(date,'%Y-%m-%d %H:'), CASE ... END)should do the job.