У меня есть следующая таблица обновлений статусов страниц. Каждая строка имеет статус изменения:
CREATE TABLE `t1` (
`page_id` int(11) NOT NULL,
`country` varchar(2) COLLATE utf8mb4_unicode_ci NOT NULL,
`status` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`date` datetime DEFAULT NULL,
PRIMARY KEY (`page_id`,`country`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO t1 (page_id, country, status, date)
VALUES (1, 'de', 'deactivated', '2018-09-28 14:52:11' ) ,
(1, 'de', 'activated', '2018-09-28 14:54:18' ) ,
(1, 'de', 'deactivated', '2018-09-28 14:60:12' ) ,
(1, 'de', 'moderated', '2018-09-28 14:54:12' ) ,
(2, 'es', 'deactivated', '2018-09-28 14:52:01' ) ,
(2, 'es', 'activated', '2018-09-28 14:52:07' ) ,
(2, 'es', 'deactivated', '2018-09-28 14:52:11' )
Я хочу видеть таблицу в таком формате, чтобы каждая строка отображалась с того момента, когда и когда страница имела определенный статус:
CREATE TABLE `t2` (
`page_id` int(11) NOT NULL,
`country` varchar(2) COLLATE utf8mb4_unicode_ci NOT NULL,
`status` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`date_from` datetime DEFAULT NULL,
`date_to` datetime DEFAULT NULL,
PRIMARY KEY (`page_id`,`country`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO t2 (page_id, country, status, date_from, date_to)
VALUES (1, 'de', 'deactivated', '2018-09-28 14:52:11', '2018-09-28 14:54:12' ) ,
(1, 'de', 'moderated', '2018-09-28 14:54:12', '2018-09-28 14:54:18' ) ,
(1, 'de', 'activated', '2018-09-28 14:54:18','2018-09-28 14:60:12' ) ,
(1, 'de', 'deactivated', '2018-09-28 14:60:12','2018-01-25 14:60:12' ) ,
(2, 'es', 'deactivated', '2018-09-28 14:52:01','2018-09-28 14:52:07' ) ,
(2, 'es', 'activated', '2018-09-28 14:52:07', '2018-09-28 14:52:11' ) ,
(2, 'es', 'deactivated', '2018-09-28 14:52:11','2018-01-25 14:52:11' ) ;
Проблема в том, что мы все еще используем MySQL 5.7 и не обновились до mysql8 с функциями cte и window, что легко решило бы проблему:
SELECT
country,
page_id,
status,
date as date_from,
COALESCE(MIN(date) OVER(PARTITION BY country, page_id ORDER BY date DESC
ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING),
TIMESTAMPADD(day, 1, current_timestamp())) as date_to
FROM t1 ;
Я предполагаю, что должен быть трюк с самостоятельным соединением, но не могу понять, как именно!