MySQL SQL-запрос с AVG по столбцу даты DISTINCT, CONCATted - PullRequest
0 голосов
/ 12 мая 2011

Итак, у меня есть следующие данные в таблице MySQL:

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)

(не секрет, это показания с устройства Current Cost)

Теперь я боролся с SQL в течение нескольких часов, чтобы получить среднее значение мощности за 15 минут.Самое близкое, что я мог бы получить:

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;

, который дает мне следующий результат:

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)

Что все еще довольно далеко от того, что я пытаюсь получить.Кажется, что я очень близок к тому, что мне нужно, просто что-то, чтобы РАЗОБРАТЬ поле даты и получить средние значения из всех полей с одинаковыми датами, но я просто не могу получить правильный SQL.

Результат, к которому я стремлюсьИбо это что-то вроде строки:

| 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 |

Любая помощь или намеки высоко ценится.

1 Ответ

0 голосов
/ 12 мая 2011

MySQL сбивается с толку, потому что вы связали свой вывод CONCAT() с тем же именем, что и существующий столбец, поэтому GROUP BY date группируется по полю таблицы таблицы, а не по округлению до ближайшая 15-минутная дата.

Вам нужно изменить запрос на что-то вроде

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 quarterhour,
    -> ROUND(AVG(power),1)
    -> FROM reading
    -> WHERE date > '2011-02-20' AND date < '2011-02-21'
    -> GROUP BY quarterhour LIMIT 0,10;

Кроме того, вместо HOUR() я бы использовал DATE_FORMAT(), чтобы обнулить часы, в противном случае «5» (5 утра) следует после «17» (5 вечера).

CONCAT(DATE_FORMAT(date,'%Y-%m-%d %H:'), CASE ... END) должен выполнить работу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...