2011-11-29 183 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