Это будет работать на MS SQL (TSQL), с ROW_NUMBER():
SELECT l1.UserID, l1.UserName, l1.LogTime AS BeginTime, l2.LogTime AS EndTime,
l1.LogDate, ROW_NUMBER() OVER (ORDER BY l1.LogDate, l1.LogTime) AS 'RowNumber'
FROM log l1
LEFT JOIN log l2
ON l2.UserID = l1.UserID
AND l2.LogTime > l1.LogTime
AND l2.LogDate = l1.LogDate
LEFT JOIN log l3
ON l3.UserID = l1.UserID
AND l3.LogTime < l2.LogTime AND l3.LogTime > l1.LogTime
AND l3.LogDate = l1.LogDate
WHERE l3.UserID IS NULL AND RowNumber % 2 = 1 AND l1.UserID = 1
ORDER BY l1.LogDate, l1.LogTime
Первое соединение объединяется в первый раз со всеми последующими моментами для одного и того же пользователя и даты. Второе соединение позволяет нам исключать все время в ту же дату и пользователя, у которых есть время между ними, что дает нам последовательные времена. Функция ROW_NUMBER позволяет нам захватывать только каждую строку, поэтому мы получаем 9:00 - 10:00
, но не 10:00 - 11:00
.
Если конечного времени нет, вы получите NULL для EndTime.
Обратите внимание, что для периодов, которые простираются от одного дня до следующего, вам нужно будет отрегулировать запрос, чтобы совместить время и дату и сравнить их вместе.
Вы не должны пытаться возвращать результаты для нескольких пользователей, иначе вы потеряете данные из-за функции мод.
SQL Server? MySQL? Какие типы полей LogTime и LogDate? – MartW
Когда у вас есть правильный ответ, вы должны принять ответ и дать кредит человеку ..... –