Есть таблица:
RecordID Date Time EventID UserID ClientID
1 |2019-02-01 |15:00 |2 |100 |5
2 |2019-02-01 |17:00 |2 |150 |5
3 |2019-02-05 |12:00 |2 |200 |5
4 |2019-02-05 |15:00 |3 |100 |5
5 |2019-02-06 |15:00 |2 |200 |5
Нужно написать запрос к базе данных MySQL, формирующий последовательные интервалы работы разных пользователей с указанным клиентом и кол-во дней работы.
Должно выйти что то вроде:
UserID DateStart DateEnd Days
100 |2019-02-01 |2019-02-01 |1
150 |2019-02-01 |2019-02-05 |5
200 |2019-02-05 |2019-02-06 |2
Я обновился до MySql 8 и использовал window function, вот что вышло:
SELECT
Date, Time, EventId, UserId,
IF (LEAD(Date) OVER W, LEAD(Date) OVER W - Date + 1, NOW() - Date) AS 'diff'
FROM first
WINDOW W AS (ORDER BY Date);
Но эта штука еще не учитывает что EventId бывает разный.
Можна сделать так :
SET sql_mode = ''; SELECT
a.UserId, MIN(a.`Date`) AS DateStart, IFNULL(b.`Date`, CURDATE()) AS DateEnd,
DATEDIFF(b.`Date`, a.`Date`) + 1 AS Days, a.EventId, a.ClientId
FROM first a LEFT JOIN first b
ON b.RecordId = ( SELECT RecordId FROM first aa WHERE aa.EventId = a.EventId AND aa.`Date` >= a.`Date` AND aa.RecordId > a.RecordId ORDER BY aa.`Date` ASC LIMIT 1 )
GROUP BY a.UserId, a.EventId, a.ClientId ORDER BY a.`RecordId` ASC;
Конечный вариан для MySql 8:
SELECT
RecordId AS RecId, Date, Time, EventId AS EvID, UserId,
CASE
WHEN (LEAD(EventId) OVER W = EventId)
THEN (LEAD(Date) OVER W - Date + 1)
WHEN (LEAD(EventId) OVER W != EventId)
THEN IF ((SELECT Date FROM first WHERE (RecordId > RecId AND EvID = EventId) LIMIT 1), DATEDIFF( (SELECT Date FROM first WHERE (RecordId > RecId AND EvID = EventId) LIMIT 1), NOW()), NOW() - Date) ELSE (NOW() - DATE)
END
AS 'diff'
FROM first WINDOW W AS (ORDER BY Date);