Поле идентификатора (в качестве ключа) и поле идентификации события после кода будут идеальными.
Если это невозможно, вам поможет функция:
DELIMITER $$
CREATE FUNCTION event_stoptime (start_time datetime)
RETURNS datetime
BEGIN
DECLARE stop_time datetime;
SET stop_time = (SELECT MIN(event_datetime) FROM events WHERE
event_datetime > start_time);
RETURN stop_time;
END $$
DELIMITER ;
Как только функция построена, вы можете объединить ее с функциями даты MySQL, чтобы получить необходимые данные:
SELECT event_datetime as event_start,
event_stoptime(event_datetime) as event_stop,
TIMEDIFF(event_stoptime(event_datetime), event_datetime) as event_duration,
WEEK(event_datetime) as event_week,
MONTH(event_datetime) as event_month
from events
where event_code = 50;
Результаты, которые я должен получить, были
| event_start | event_stop | duration | week| month|
'2018-01-01 06:00:00', '2018-01-01 07:00:00', '01:00:00', '0', '1'
'2018-01-01 11:00:00', '2018-01-01 13:00:00', '02:00:00', '0', '1'
'2018-01-02 07:00:00', '2018-01-02 23:00:00', '16:00:00', '0', '1'
'2018-01-24 07:00:00', '2018-01-25 23:00:00', '40:00:00', '3', '1'
'2018-02-02 10:00:00', '2018-02-02 12:00:00', '02:00:00', '4', '2'
БОЛЬШОЙ БОЛЬШОЙ ПРОСМОТР: Еслинет соответствующего события 54 для заданных 50 (из-за ошибки и т. д.), времена будут сильно искажены.
Вот лучшее решение с использованием поля ID.Я включил идентификатор в оператор вставки для простоты тестирования:
CREATE TABLE `events` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`event_datetime` datetime DEFAULT NULL,
`event_code` varchar(40) DEFAULT NULL,
`val` varchar(40) DEFAULT NULL,
`event_id` int(11) DEFAULT NULL,
PRIMARY KEY (`ID`)
);
INSERT INTO `events`
VALUES (1,'2018-01-01 06:00:00','50','1',NULL),
(2,'2018-01-01 07:00:00','54',NULL,1),
(3,'2018-01-01 11:00:00','50','2',NULL),
(4,'2018-01-01 13:00:00','54',NULL,3),
(5,'2018-01-01 09:00:00','50',NULL,NULL),
(6,'2018-01-02 23:00:00','54',NULL,5),
(7,'2018-01-24 07:00:00','50','1',NULL),
(8,'2018-01-25 23:00:00','54','3',7),
(9,'2018-02-02 10:00:00','50','1',NULL),
(10,'2018-02-02 12:00:00','54',NULL,9),
(11,'2018-01-30 23:00:00','54','3',NULL);
Представление присоединяет таблицу к себе, чтобы выбрать правильные значения от «54» до «50».Обратите внимание на создание даты для поиска первой недели месяца:
CREATE VIEW `event_list` AS
select `events`.`ID` AS `ID`,`events`.`event_datetime` AS `event_start`,
`end_events`.`event_datetime` AS `event_stop`,
timediff(`end_events`.`event_datetime`,`events`.`event_datetime`) AS `event_duration`,
week(`events`.`event_datetime`) AS `event_week`,
month(`events`.`event_datetime`) AS `month_number`,
monthname(`events`.`event_datetime`) AS `event_month`,
WEEK(STR_TO_DATE(concat(year(events.event_datetime), '-', month(events.event_datetime), '-', '01'), '%Y-%m-%d')) as first_week
from (`events` left join `events` `end_events` on((`events`.`ID` = `end_events`.`event_id`)))
where (`events`.`event_code` = '50');
Оператор выбора использует IF для выбора правильных данных для сводок за неделю.Время вычисляется в секундах для расчета длительности, затем снова собирается для отображения;
select event_month,
sec_to_time(sum(time_to_sec(if(event_week = first_week, event_duration, 0)))) as week_one,
sec_to_time(sum(time_to_sec(if(event_week = first_week + 1, event_duration, 0)))) as week_two,
sec_to_time(sum(time_to_sec(if(event_week = first_week + 2, event_duration, 0)))) as week_three,
sec_to_time(sum(time_to_sec(if(event_week = first_week + 3, event_duration, 0)))) as week_four,
sec_to_time(sum(time_to_sec(if(event_week = first_week + 4, event_duration, 0)))) as week_five
from event_list
group by event_month
order by month_number
Не элегантно, но работает.