2015-10-29 5 views
2

Предоставлена ​​таблицей со следующими полями:MySQL: Создать «сеанс» событий между двумя датами

username | event    | time (hh:mm:ss)  
user2 | login    | 03:27:17 
user2 | check messages  | 03:31:31 
user2 | view profile  | 03:32:01 
user2 | logout    | 03:32:48 
user3 | login    | 13:00:59 
user3 | change billing info | 13:03:11 
user3 | logout    | 13:03:32 

я пытаюсь создать пользователь «сессию», используя в первый раз, как «Вход» время и в последний раз, как время выхода из системы. Полученная таблица должна быть:

username | event    | login time | event time | logout time 
user2 | login    | 03:27:17 | 03:27:17 | 03:32:48 
user2 | check messages  | 03:27:17 | 03:31:31 | 03:32:48 
user2 | view profile  | 03:27:17 | 03:32:01 | 03:32:48 
user2 | logout    | 03:27:17 | 03:32:48 | 03:32:48 
user3 | login    | 13:00:59 | 13:00:39 | 13:03:32 
user3 | change billing info | 13:00:59 | 13:03:11 | 13:03:32 
user3 | logout    | 13:00:59 | 13:03:32 | 13:03:32 

Я пытался использовать мин (время) и макс (время), чтобы получить вход и выход разы, но когда я делаю, я получаю раз Войти, событие и выход из системы, что смешиваются.

SELECT login.eventTime, actualEvent.eventTime, logout.eventTime 
FROM tableName login, tableName actualEvent, tableName logout 
WHERE login.username = actualEvent.username 
AND actualEvent.username = logout.username 
AND login.eventTime = 
    (SELECT MIN(minTime.eventTime) 
    FROM tableName minTime 
    WHERE minTime.username = login.username) 
AND logout.eventTime = 
    (SELECT MAX(maxTime.eventTime) 
    FROM tableName maxTime 
    WHERE maxTime.username = login.username) 
AND login.eventTime < logout.eventTime; 

Любая помощь была бы принята с благодарностью.

EDIT: Ответ от @Bernd Buffen хорошо работает, за исключением случаев, когда время происходит на нескольких датах. Например:

username | event    | time (hh:mm:ss)  
user2 | login    | 08/11/2015 03:27:17 
user2 | check messages  | 08/11/2015 03:31:31 
user2 | view profile  | 08/11/2015 03:32:01 
user2 | logout    | 08/11/2015 03:32:48 
user3 | login    | 08/11/2015 13:00:59 
user3 | change billing info | 08/11/2015 13:03:11 
user3 | logout    | 08/11/2015 13:03:32 
user2 | login    | 08/12/2015 04:00:00 
user2 | change billing info | 08/12/2015 04:03:22 
user2 | logout    | 08/12/2015 04:08:17 

В этом случае моя выходная таблица имеет время окончания сеанса, которое находится на несколько дней вперед. Любые рекомендации по устранению этого?

+0

Вставить текущую команду SQL вы используете, чтобы мы могли посмотреть. – jpaljasma

+0

Почему контрольные сообщения и вид профиля находятся в фактическом времени входа в систему? – Tarek

ответ

1

Предположив ваше имя таблицы рубки, я думаю, что это поможет (не проверено):

SELECT l.username, l.event, login_time, event_time, logout_time 
FROM loggings l 

LEFT JOIN (
    SELECT MIN(`time`) AS login_time, username FROM loggings 
    GROUP BY username 
) login_tbl 
ON l.username=login_tbl.username 

LEFT JOIN (SELECT `time` AS event_time, username FROM loggings) event_tbl 
ON l.username=event_tbl.username 

LEFT JOIN (
    SELECT MAX(`time`) AS logout_time, username FROM loggings 
    GROUP BY username 
) AS logout_tbl 
ON l.username=logout_tbl.username 
0

Вы должны также убедиться, что если тот же пользователь имеет два сеанса, каждый со своим соответствующим логином и выхода из системы событий, вы соответствуете правой паре событий входа/выхода из системы в выбранное вами событие. Обратите внимание, что для достижения этого вы должны фактически максимизировать время входа в систему и минимизировать время выхода из системы. Разумеется, оба должны оставаться на правильной стороне реального события. Поэтому я бы предложил следующее:

SELECT  actualEvent.username 
     , actualEvent.event 
     , MAX(login.eventTime) loginTime 
     , actualEvent.eventTime 
     , MIN(logout.eventTime) logoutTime 
FROM  tableName actualEvent 
INNER JOIN tableName login 
     ON actualEvent.username = login.username 
     AND actualEvent.evenTime >= login.eventType 
     AND login.eventType = 'login' 
INNER JOIN tableName logout 
     ON actualEvent.username = logout.username 
     AND actualEvent.evenTime <= logout.eventType 
     AND logout.eventType = 'logout' 
GROUP BY actualEvent.username 
     , actualEvent.event 
     , actualEvent.eventTime 
ORDER BY actualEvent.eventTime; 
0

Попробуйте это. Я надеюсь, что то, то вы хотите

SELECT 
    t.`username`, 
    t.`event`, 
    min(l.`time`) AS 'event_login', 
    t.`time` AS 'event_time', 
    max(l.`time`) AS 'event_logout' 
FROM mytable t 
LEFT JOIN mytable l ON t.username = l.username 
GROUP BY t.username,t.event 
ORDER BY `username` ASC, t.time; 

Результат:

+----------+---------------------+-------------+------------+--------------+ 
| username | event    | event_login | event_time | event_logout | 
+----------+---------------------+-------------+------------+--------------+ 
| user2 | login    | 03:27:17 | 03:27:17 | 03:32:48  | 
| user2 | check messages  | 03:27:17 | 03:31:31 | 03:32:48  | 
| user2 | view profile  | 03:27:17 | 03:32:01 | 03:32:48  | 
| user2 | logout    | 03:27:17 | 03:32:48 | 03:32:48  | 
| user3 | login    | 13:00:59 | 13:00:59 | 13:03:32  | 
| user3 | change billing info | 13:00:59 | 13:03:11 | 13:03:32  | 
| user3 | logout    | 13:00:59 | 13:03:32 | 13:03:32  | 
+----------+---------------------+-------------+------------+--------------+ 
7 rows in set (0.00 sec) 
+0

Это работает, за исключением случаев, когда даты различаются (у пользователя2 есть сеанс на две разные даты). Какие-либо предложения? – bspitch1

+0

@ bspitch1 Можете ли вы мне дать образец даты ввода от пользователя2, где он не работает, а затем исправит его. –

+0

Если время входа в систему - это значение даты, и пользователь входит в систему, проверяет сообщения и выходит из системы на двух разные даты. Поэтому из приведенной выше таблицы добавьте: user2 login @ 12/21/2014 14:17:07, user2 check messages @ 12/21/2014 14:18:00, user2 logout @ 12/21/2014 14:18:59 , Имеет ли это смысл? – bspitch1

Смежные вопросы