2017-06-17 96 views
0

我想計算2行之間的時間差 - 但它有點棘手,然後通常。用戶在進入時收到temporally_id。此ID不是唯一的 - 這意味着在此用戶離開後,只有在第一位用戶離開後,新用戶可能會得到相同的temporally_id,但通常爲(請參閱下面的說明)。入口表看起來像這樣(entrance_states - 1:輸入,2:退出):mysql - 行時間差再次

| temporally_id | entrance_state | entrance_date | 
----------------------------------------------------- 
| 111  |  1  | 2017-01-01 10:20 | 
| 222  |  1  | 2017-01-01 11:00 | 
| 222  |  2  | 2017-01-01 11:20 | 
| 222  |  1  | 2017-01-01 18:00 | 
| 111  |  2  | 2017-01-01 21:00 | 
| 111  |  1  | 2017-01-01 22:15 | 
| 222  |  2  | 2017-01-02 01:00 | 
| 111  |  2  | 2017-01-02 02:15 | 

正如你所看到的 - 用戶也可以留在裏面,直到第二天。 我的願望是:

| temporally_id | entrance_date | timediff | 
----------------------------------------------- 
| 111  | 2017-01-01 10:20 | 11,50 h | 
| 222  | 2017-01-01 11:00 | 0,33 h | 
| 222  | 2017-01-01 18:00 | 7,00 h | 
| 111  | 2017-01-01 22:15 | 4,00 h | 

所以基本上我想要一個時差。最棘手的部分是,有時,「退出」沒有被記錄 - 所以在表中,它看起來像狀態1在相同的temporally_id(這再次不正常並且不應該是)相同的狀態1之後。還有,因爲我必須考慮這種故障並檢查狀態1是否其次是狀態2

這裏是我的SQL查詢:

SELECT avg(TIMESTAMPDIFF(MINUTE,A.date,B.date)/60) as `diff` 
FROM (SELECT 
     entrance_date as date, 
     temporally_id 
     FROM `entrance` 
     WHERE entrance_state = 1 
     order by temporally_id asc, entrance_date asc) A 
LEFT JOIN   
    (SELECT 
     entrance_date as date, 
     temporally_id 
     FROM `entrance` 
     WHERE action_id = 2 
     order by temporally_id asc, activity_date asc) 
     B ON A.temporally_id = B.temporally_id 

不幸的是,這是不是給我我需要什麼。

+0

這是一個非常困難的問題,充滿了邊緣案例和異常情況。這是我會建議使用遊標編寫邏輯或在應用程序中少數幾次之一。 –

+0

我建議在表中添加一個user_id,以便您可以確定它們何時離開,而不是通過數據流來推斷它。 –

+0

不幸的是,我不能添加一個用戶ID給他們 - 至少不是在這一點 –

回答

0

「temporally_id」是英語的濫用。你的意思是「temporary_id」。

由於不能自動確定「temporary_id」未被使用,因此您無法使這個「temporary_id」的想法起作用,重複使用它。所以,你有競爭條件,其中兩個用戶大約同時進入收到相同的「temporary_id」。

在任何情況下,如果您堅持嘗試,那麼您需要通過消除「退出」未記錄的情況來降低此問題的複雜性。所以,讓你的表經過一遍,選擇所有沒有記錄「退出」的行,並將他們的「退出」時間設置爲「入口」時間,例如20分鐘。 (一種常用的網絡會話超時)

+0

謝謝 - 關於「temorary」-word我waswawair :)如果我會在我的應用程序中編寫一個循環,將搜索和編輯此表,那麼我也可以用這個循環來計算這個時間差。但可能這是一個更好的方式,因爲問題太不尋常了 –

0

而是基於entrance_state處理記錄,我會建議處理基於temporally_identrance_date的記錄,例如:

SELECT * 
FROM entrance 
ORDER BY temporally_id, entrance_date 

這將使你的ID進行排序的結果和日期,然後您可以在應用程序或存儲過程中編寫一個邏輯,以便跟蹤之前處理的記錄,將當前記錄的temporally_identrance_state與它相比較,並相應地輸出/忽略它。

+0

是的 - 這也是@ gordon-linoff建議的。在應用程序中編寫邏輯始終是一種選擇,但我想知道是否有更聰明的方法只使用SQL來完成此操作 –