Как верно подметил Дмитрий - знание SQL наше все.
Вот к примеру я создал тестовую таблицу и наполнил ее тестовыми данными:
CREATE TABLE `test001` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`TimeFrom` datetime DEFAULT NULL,
`InA` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8;
INSERT INTO `test001` VALUES ('1', '2020-05-17 16:14:36', '1');
INSERT INTO `test001` VALUES ('2', '2020-05-17 16:12:56', '2');
INSERT INTO `test001` VALUES ('3', '2020-05-17 16:12:56', '3');
INSERT INTO `test001` VALUES ('4', '2020-05-17 17:12:56', '4');
INSERT INTO `test001` VALUES ('5', '2020-05-17 17:12:56', '5');
INSERT INTO `test001` VALUES ('6', '2020-05-17 17:12:56', '6');
INSERT INTO `test001` VALUES ('7', '2020-05-17 18:12:56', '7');
INSERT INTO `test001` VALUES ('8', '2020-05-17 18:12:56', '8');
INSERT INTO `test001` VALUES ('9', '2020-05-17 18:12:56', '9');
INSERT INTO `test001` VALUES ('10', '2020-05-17 19:12:56', '10');
INSERT INTO `test001` VALUES ('11', '2020-05-17 19:12:56', '11');
INSERT INTO `test001` VALUES ('12', '2020-05-17 19:12:56', '12');
INSERT INTO `test001` VALUES ('13', '2020-05-17 20:12:56', '13');
INSERT INTO `test001` VALUES ('14', '2020-05-17 20:12:56', '14');
INSERT INTO `test001` VALUES ('15', '2020-05-17 20:12:56', '15');
INSERT INTO `test001` VALUES ('16', '2020-05-17 21:12:56', '16');
INSERT INTO `test001` VALUES ('17', '2020-05-17 21:12:56', '17');
INSERT INTO `test001` VALUES ('18', '2020-05-17 21:12:56', '18');
Для получения почасовых сумм по полю InA мне достаточно очень простого запроса:
SELECT
FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(test001.TimeFrom) / 3600) * 3600),
SUM(test001.InA) as SumInA
FROM
test001
GROUP BY
FLOOR(UNIX_TIMESTAMP(test001.TimeFrom) / 3600) * 3600
Результат запроса будет выглядеть вот так:
2020-05-17 16:00:00 6
2020-05-17 17:00:00 15
2020-05-17 18:00:00 24
2020-05-17 19:00:00 33
2020-05-17 20:00:00 42
2020-05-17 21:00:00 51
Скорость выдачи результата будет большой - при миллионах записей в исходной таблице дело нескольких секунд или десятков секунд (зависит от железа сервера).
Но это все равно медленно, потому что на каждую запись таблицы будет производится вычисление "FLOOR(UNIX_TIMESTAMP(test001.TimeFrom) / 3600) * 3600" - деление, округление и умножение.
Если это разовая выборка - проблем нет. Но если вам нужно регулярно дергать из таблицы данные, то лучше добавить в таблицу поле TimeFromHour, в которое сразу записывать значение FLOOR(UNIX_TIMESTAMP(test001.TimeFrom) / 3600) * 3600. Это можно сделать руками или триггером при вставке. Добавить Индекс по полю TimeFromHour и в запросе тоже группировать (GROUP BY) по этому полю:
ALTER TABLE `test001`
ADD INDEX `Index-TimeFromHour` (`TimeFromHour`) USING BTREE ;
Тогда вы получите максимально возможное быстродействие.
Если нужно результат вставить в другую таблицу, то используйте запрос вроде такого:
INSERT INTO
test_sum
(TimeFrom, SumInA)
(
SELECT
FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(test001.TimeFrom) / 3600) * 3600),
SUM(test001.InA) as SumInA
FROM
test001
GROUP BY
FLOOR(UNIX_TIMESTAMP(test001.TimeFrom) / 3600) * 3600
)