在我的sql中在同一列下配对日期

时间:2014-04-06 14:53:48

标签: mysql

如何在我的sql中的同一列下配对日期?

表格如下:

id | user       | type        | date
---+------------+-------------+-------------
 1 |          1 |    login    |  2014-03-19 15:41:52
 2 |          1 |    login    |  2014-03-19 19:41:52
 3 |          1 |    logout   |  2014-03-19 21:41:52
 4 |          2 |    login    |  2014-03-20 19:41:52
 5 |          2 |    logout   |  2014-03-20 20:41:52
 6 |          3 |    login    |  2014-03-21 19:41:52
 7 |          4 |    login    |  2014-03-21 19:42:52
 8 |          4 |    logout   |  2014-03-21 21:41:52
10 |          5 |    login    |  2014-03-19 21:45:52
11 |          5 |    login    |  2014-03-19 21:46:52
12 |          3 |    logout   |  2014-03-19 21:51:52
13 |          5 |    logout   |  2014-03-19 22:41:52

目的是将一次登录与一次登出配对 在此示例中,用户1有2次登录和1次注销。

第一次登录应该被忽略,最近的登录应该与最小注销配对:即配对登录id = 2和注销id = 3

3 个答案:

答案 0 :(得分:0)

容易......

select 
  user,
  type,
  max(date)
from  
  user_table
group by
  user,
  type

第一个查询获取最大登录和注销日期,但听起来您希望它们匹配。我需要更多信息来编写更清晰的脚本。根据你提供的内容,听起来你想要下面的查询。

select
  t1.user,
  t1.max_login_date,
  t1.max_logout_date
from
  (select
    user,
    max(date) max_login_date
  from
    user_table
  where
    type = 'login'
  group by
    user) t1

  left join
      (select
      user,
      max(date) max_logout_date
    from
      user_table
    where
      type = 'logout'
    group by
      user) t2 on
      t2.user = t1.user

此查询获取每个用户的最大登录日期,并且您希望将最大注销日期与该登录日期相匹配。

答案 1 :(得分:0)

这样的东西可能会起作用,应该从表中返回所有组合,但随着表填充,性能可能会变差。为了获得更好的性能,请考虑向表中添加唯一生成的SessionId,这对于Login和Logout都是相同的。

SELECT t1.user, t1.date loginDate, t2.date LogoutDate 
FROM table t1 
LEFT JOIN table t2 
    ON t1.user = t2.user AND t1.type = 'login' and t2.type = 'logout' AND t1.Date < t2.Date 
LEFT JOIN table t3 
    ON t3.user = t1.user AND t3.type = 'login' and t3.date < t2.date 
WHERE t3.id IS NULL

答案 2 :(得分:0)

我想出了如何选择相关的登录:)

结果集中有登录和注销字段...
它几乎捕获了所有真正的对... 只有正确的序列登录/注销才能正常工作...
非常重查询,我建议把这个逻辑移到php(或其他你的lang)那边......

set @ll=null;
SELECT t1.pk,t1.u, t1.t logout, related login FROM
(SELECT 
  @rl:=IF((a.a='<'), (@ll), null) related,
  IF((a.a='>'), @ll:=a.t, IF(a.a='<', @ll:=null, null)) `_`,
  a.*
  FROM
  (SELECT * FROM A ORDER BY u, t) a)t1 WHERE t1.a='<'

在测试数据集中:
>表示登录
<表示注销

SQLFiddle

PS: 只有"but as of the moment i am constraint to do it in mysql"是编写它的原因)