MySQL не может определить функциональную зависимость ... между выражениями в предложении GROUP BY и выражениями в списке SELECT.
Неагрегированное выражение в списке SELECT (DATE_FORMAT(date_time, '%H:%i')
включает компонент минут. Предложение GROUP BY собирается свернуть строки в группы всего за час. Таким образом, значение минуты неопределенны ... мы знаем, что это произойдет из какого-то ряда в группе, но нет гарантии, какой именно.
(Ссылка на вопрос ONLY_FULL_GROUP_BY
, кажется, указывает на то, что у нас есть некоторое понимание неопределенных значений ...)
Самое простое (наименьшее) исправление изменений - заключить это выражение в функцию MIN
или MAX
.
SELECT MAX(t.counter) AS `max`
, MIN(t.counter) AS `min`
, MIN(DATE_FORMAT(t.date_time,'%H:%i')) AS `dt`
FROM table1 t
WHERE t.date_time >= NOW() - INTERVAL 1 DAY
GROUP
BY YEAR(t.date_time)
, MONTH(t.date_time)
, DAY(t.date_time)
, HOUR(t.date_time)
ORDER
BY YEAR(t.date_time)
, MONTH(t.date_time)
, DAY(t.date_time)
, HOUR(t.date_time)
Если мы хотим, чтобы строки возвращались в определенном порядке, мы должны включить предложение ORDER BY
, а не полагаться на специфичное для MySQL расширение или поведение GROUP BY
(которое может исчезнуть в будущих выпусках.)
Немного странно делать GROUP BY
год, месяц, день и не включать эти значения в список SELECT. (Это не является недействительным, просто странно. Условия в предложении WHERE
гарантируют, что у нас не более 24 часов для date_time
.
Я бы предпочел сделать GROUP BY
в том же выражении, что и неагрегат в списке SELECT. Если бы мне понадобилось больше 24 часов, я бы включил компонент даты:
SELECT MAX(t.counter) AS `max`
, MIN(t.counter) AS `min`
, DATE_FORMAT(t.date_time,'%Y-%m-%d %H:00') + INTERVAL 0 DAY AS `dt`
FROM table1 t
WHERE t.date_time >= NOW() - INTERVAL 1 DAY
GROUP
BY DATE_FORMAT(t.date_time,'%Y-%m-%d %H:00') + INTERVAL 0 DAY
ORDER
BY DATE_FORMAT(t.date_time,'%Y-%m-%d %H:00') + INTERVAL 0 DAY
- или -
, если мы всегда знаем, что это всего лишь стоимость одного дня date_time
, и мы хотим вернуть только час, то мы можем сгруппировать по часам. То же выражение, что и в списке SELECT.
SELECT MAX(t.counter) AS `max`
, MIN(t.counter) AS `min`
, DATE_FORMAT(t.date_time,'%H:00') AS `dt`
FROM table1 t
WHERE t.date_time >= NOW() - INTERVAL 1 DAY
GROUP
BY DATE_FORMAT(t.date_time,'%H:00')
, DATE_FORMAT(t.date_time,'%Y-%m-%d %H')
ORDER
BY DATE_FORMAT(t.date_time,'%Y-%m-%d %H')