2011-11-29 140 views
0

我有这个MySQL查询,当我搜索一个用户,他有一个登录(开始 - 结束)它显示下一行的总数好,但如果用户有多个登录(开始 - 结束)它不显示总的下一行....MySQL子查询计算

SELECT CONCAT(u.lastname, ', ', u.firstname) AS Name 
    , start.timestamp start 
    , end.timestamp end 
    , timediff(end.timestamp, start.timestamp) duration 
FROM user u 
    , user_group ug 
    , (
     select * 
     , (
      select event_id 
      from event L2 
      where L2.timestamp > L1.timestamp 
       and L2.user_bannerid = L1.user_bannerid 
      order by timestamp limit 1 
      ) stop_id 
     From event L1 
    ) start 
join event end on end.event_id = start.stop_id 
where start.status = 'In' 
    and end.status='Out' 
    and u.user_bannerid = start.user_bannerid 
    and ug.user_bannerid = u.user_bannerid 
    and ug.group_id = start.group_id 

UNION 

SELECT null, null, null, CAST(sum(duration) as Time) 
FROM 
(
    SELECT CONCAT(u.lastname, ', ', u.firstname) AS Name 
     , start.timestamp start 
     , end.timestamp end 
     , timediff(end.timestamp, start.timestamp) duration 
    from user u 
     , user_group ug 
     , (
     select * 
     , (
      select event_id 
      from event L2 
      where L2.timestamp > L1.timestamp 
       and L2.user_bannerid = L1.user_bannerid 
      order by timestamp 
      limit 1 
      ) stop_id 
     from event L1 
     ) start 
    join event end on end.event_id = start.stop_id 
    where start.status = 'In' 
     and end.status = 'Out' 
    and u.user_bannerid = start.user_bannerid 
    and ug.user_bannerid = u.user_bannerid 
     and ug.group_id = start.group_id 
) total 

它显示总好吗当用户只需登录一次

+----------------------------------------------------+---------------+ 
| Name | start    | end     | duration  |  
+----------------------------------------------------+---------------+ 
| User | 2011-11-24 02:12:05 | 2011-11-24 02:12:20 | 00:00:15  |  
|  |      |      | 00:00:15  | 
+----------------------------------------------------+---------------+ 

但是,当用户有不止一个登录,它不显示总小时数,

+----------------------------------------------------+---------------+ 
    | Name | start    | end     | duration  |  
    +----------------------------------------------------+---------------+ 
    | User | 2011-11-24 02:12:05 | 2011-11-24 02:12:20 | 00:00:15  |  
    | User | 2011-11-28 21:46:54 | 2011-11-28 21:53:01 | 00:06:17  | 
    |  |      |      |    | 
    +----------------------------------------------------+---------------+ 

即时猜测它必须与限制,但如果我将限制超过1我得到“的错误没有1242子查询返回多个行。”有人可以帮我改写查询来显示总小时数,无论他们有多少登录名?

编辑:

仍然有,所以我想出了一个新的查询,但后来我不断收到的无效,而不是总有这样的问题。 任何想法,为什么这样呢?

+----------------------------------------------------+---------------+ 
| Name | start    | end     | duration  |  
+----------------------------------------------------+---------------+ 
| User | 2011-11-24 02:12:05 | 2011-11-24 02:12:20 | 00:00:15  |  
| User | 2011-11-28 21:46:54 | 2011-11-28 21:53:01 | 00:06:17  | 
| User | 2011-11-28 21:46:54 | 2011-11-28 21:53:01 | null   | 
+----------------------------------------------------+---------------+ 

SELECT 
    CONCAT(u.lastname, ', ', u.firstname) AS Name, 
    start.timestamp AS start, 
    end.timestamp AS end, 
    TIME(SUM(TIMEDIFF(end.timestamp, start.timestamp))) AS duration 
FROM user AS u 
    INNER JOIN user_group AS ug ON u.user_bannerid = ug.user_bannerid 
    INNER JOIN event AS start ON start.user_bannerid = u.user_bannerid AND start.status='In' AND start.group_id = ug.group_id 
    INNER JOIN event AS end ON end.user_bannerid = u.user_bannerid AND end.status='Out' AND start.event_id < end.event_id 
GROUP BY start.event_id WITH ROLLUP 
+0

哪里'00:00:32'来自第一个“好的”结果? – newtover

+0

抱歉错别字...其总共00:00:15 – user1012135

+0

我们看到结果...您可以发布一些原始数据,这是此查询结果的基础...即使只显示假用户名称,但ID,状态,组,时间戳条目。另外,如果一个人在一行中有两个LOG“IN”条目而它们之间没有相应的Log“OUT”,那么它是否有可能? – DRapp

回答

0

我觉得你最好的选择将是一个stop_id添加到事件表,那么当用户注销时,更新事件从脱离事故记录ID。

对于现有记录,您可以编写一个查询来根据问题中的逻辑更新记录。

一旦你这样做了,因为你在事件表中有一个stop_id,获取开始和结束时间是一个相对简单的查询。

离开了现在的用户信息,这是所有你需要了解详细内容:

SELECT start.timestamp start , 
     end.timestamp end , 
     timediff(end.timestamp, start.timestamp) duration 
    FROM event start join event end on end.event_id = start.stop_id 

你并不需要测试的启动或停止状态,因为可能只有一个状态这些事件In将有一个stop_id和内部联接(假设这是mysql中的联接)防止Out记录被包含在顶层。

+0

请阅读主要问题的编辑部分。谢谢 – user1012135