У меня есть структура таблицы, которая выглядит так:
+---------+------------+----------+---------+-----------+------------+
| id | account_id | hashrate | workers | sharerate | timestamp |
+---------+------------+----------+---------+-----------+------------+
| 1227368 | 42 | 405211 | 1 | 6183 | 1534264380 |
| 1227367 | 12 | 450077 | 1 | 6868 | 1534264380 |
+---------+------------+----------+---------+-----------+------------+
Строка создается каждую минуту для пользователя с активным работником.
Я пытаюсь отобразить график, который будет показывать среднюю хешетацию и увеличивать ее в течение часа в течение 24 часов.
Мой запрос sql:
SELECT
timestamp,
SUM(hashrate) as hashes,
SUM(sharerate) AS shares
FROM statistics_users
WHERE FROM_UNIXTIME(timestamp) >= DATE_SUB(NOW(), INTERVAL 1 DAY)
GROUP BY timestamp;
который возвращает:
+------------+------------+----------+
| timestamp | hashes | shares |
+------------+------------+----------+
| 1534177980 | 2282744244 | 34831913 |
Который возвращает 1440 объектов (по одной на каждую минуту дня). Я хочу группировать элементы по часам и усреднять все суммы, возвращенные из моего запроса минут в час. Не уверен, куда идти отсюда, и я довольно новичок в написании запросов sql, поэтому любая помощь будет высоко оценена.
Мы можем использовать выражение, которое возвращает представление часа, в основном обрезание минут и секунд, а затем GROUP BY
это выражение. Одна возможность использовать функцию MySQL DATE_FORMAT
.
SELECT DATE_FORMAT(FROM_UNIXTIME(t.timestamp),'%Y-%m-%d %H') AS ts_hr
, AVG(t.hashes)
, AVG(t.shares)
FROM (
-- original query goes here as inline view
SELECT timestamp
, SUM(hashrate) as hashes
, SUM(sharerate) AS shares
FROM statistics_users
WHERE FROM_UNIXTIME(timestamp) >= NOW() + INTERVAL -1 DAY
GROUP BY timestamp
) t
GROUP
BY DATE_FORMAT(FROM_UNIXTIME(t.timestamp),'%Y-%m-%d %H')
-- ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
Обратите внимание, что условие в предложении WHERE не соответствует часовым границам, поэтому мы получим частичный результат за первый час и частичный последний час.
Спецификация неясна, хотим ли мы получать среднее значение сумм за каждую метку времени или проще
SELECT DATE_FORMAT(FROM_UNIXTIME(t.timestamp),'%Y-%m-%d %H') AS ts_hr
, AVG(t.hashrate)
, AVG(t.sharerate)
FROM statistics_users t
WHERE FROM_UNIXTIME(t.timestamp) >= NOW() + INTERVAL -1 DAY
GROUP
BY DATE_FORMAT(FROM_UNIXTIME(t.timestamp),'%Y-%m-%d %H')
-- ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-format
GROUP BY Hour(timestamp);