2013-05-03 54 views
0

登錄/註銷事件記錄在一張類似的表格之間的合作:獲取小時套日期

user_id  object_id date_event 
7   2   2013-05-03 08:37:11 
7   3   2013-05-03 12:43:51 
7   2   2013-05-03 15:33:41 
7   3   2013-05-03 17:10:01 

有記錄的其他對象,但2和3是重要的(2 =登錄,3 =登出)。

我有一個查詢的麻煩,將顯示一個總計的登陸,小時我用this爲出發點,但我的查詢返回null登錄的總時間。

 SELECT 
      el.user_id, 
      TIME(SUM(el.date_event*(1-2*el.object_id))) AS total_time 
     FROM 
      event_log el 
     WHERE 
      DATE(el.date_event) = '2013-05-03' AND 
      el.object_id IN (2,3) AND 
      el.user_id = 9 
     GROUP BY 
      el.user_id; 

這yeilds:

user_id  total_time 
9   NULL 

當我想到

user_id  total_time 
9   05:43:00 

爲什麼回報IN NULL?數據集中沒有空值。

+0

在另一個例子中,當你試圖輸入你的object_id時,他使用1s和0s,並且你正在使用2s和3s。他使用1和0來設置正面和負面。你的工作不會一樣。嘗試一個case語句將2變爲1,三個變爲0. – Leeish 2013-05-03 21:59:29

+0

我不知道這是否能解決它,但我至少可以看到這是您的邏輯不同的地方。 – Leeish 2013-05-03 22:01:42

回答

2

假設3註銷和2登錄

SELECT T1.user_id, 
     T1.date_event, 
     MIN(TimeDiff((T2.date_event), T1.date_event)) AS DaysDiff 
FROM YourTable T1 
     LEFT JOIN YourTable T2 
      ON T1.user_id = T2.user_id 
      AND T2.date_event > T1.date_event 
WHERE T1.object_id = 2 AND T2.object_id = 3 
GROUP BY T1.user_id, 
     T1.date_event 
+0

目前沒有工作,給我一個編輯的機會 – 2013-05-03 22:10:25

+0

這裏唯一的問題是它不能很好地處理丟失的數據。例如兩個連續登錄沒有註銷。有可能用MySQL來處理但不容易使用 – 2013-05-03 22:10:52

+1

你只需要將TIMEDIFF的參數取反,然後在min之後而不是之前。 [看到這個小提琴](http://sqlfiddle.com/#!2/bf2c0/12)來修復它 – 2013-05-03 22:17:39

2

我有另一種方法

SET @given_user = 7; 
SET @dt = '2013-05-03'; 
SET @dt1 = @dt + INTERVAL 0 SECOND; 
SET @dt2 = @dt + INTERVAL 1 DAY; 
SELECT 
    SEC_TO_TIME(SUM(dts)) TotalTime 
FROM 
(
    SELECT 
     (IF(object_id=2,-1,1) * 
     (UNIX_TIMESTAMP(date_event) - 
     UNIX_TIMESTAMP(DATE(date_event) +INTERVAL 0 SECOND))) dts 
    FROM 
     event_log 
    WHERE 
     [email protected]_user AND 
     object_id IN (2,3) AND 
     date_event >= @dt1 AND 
     date_event < @dt2 
) A; 

這是你的樣本數據

use test 
DROP TABLE IF EXISTS event_log; 
CREATE TABLE event_log 
(
    id INT NOT NULL AUTO_INCREMENT, 
    user_id INT NOT NULL, 
    object_id INT NOT NULL, 
    date_event DATETIME, 
    PRIMARY KEY (id) 
); 
INSERT into event_log 
(user_id,object_id,date_event) VALUES 
(7,2,'2013-05-03 08:37:11'), 
(7,3,'2013-05-03 12:43:51'), 
(7,2,'2013-05-03 15:33:41'), 
(7,3,'2013-05-03 17:10:01'); 

這被載入

use test 
Database changed 
mysql> DROP TABLE IF EXISTS event_log; 
Query OK, 0 rows affected (0.00 sec) 

mysql> CREATE TABLE event_log 
    -> (
    ->  id INT NOT NULL AUTO_INCREMENT, 
    ->  user_id INT NOT NULL, 
    ->  object_id INT NOT NULL, 
    ->  date_event DATETIME, 
    ->  PRIMARY KEY (id) 
    ->); 
Query OK, 0 rows affected (0.05 sec) 

mysql> INSERT into event_log 
    -> (user_id,object_id,date_event) VALUES 
    -> (7,2,'2013-05-03 08:37:11'), 
    -> (7,3,'2013-05-03 12:43:51'), 
    -> (7,2,'2013-05-03 15:33:41'), 
    -> (7,3,'2013-05-03 17:10:01'); 
Query OK, 4 rows affected (0.00 sec) 
Records: 4 Duplicates: 0 Warnings: 0 

mysql> 

下面是該查詢執行

mysql> SET @given_user = 7; 
Query OK, 0 rows affected (0.00 sec) 

mysql> SET @dt = '2013-05-03'; 
Query OK, 0 rows affected (0.00 sec) 

mysql> SET @dt1 = @dt + INTERVAL 0 SECOND; 
Query OK, 0 rows affected (0.00 sec) 

mysql> SET @dt2 = @dt + INTERVAL 1 DAY; 
Query OK, 0 rows affected (0.00 sec) 

mysql> SELECT 
    ->  SEC_TO_TIME(SUM(dts)) TotalTime 
    -> FROM 
    -> (
    ->  SELECT 
    ->   (IF(object_id=2,-1,1) * 
    ->   (UNIX_TIMESTAMP(date_event) - 
    ->   UNIX_TIMESTAMP(DATE(date_event) +INTERVAL 0 SECOND))) dts 
    ->  FROM 
    ->   event_log 
    ->  WHERE 
    ->   user_id=7 AND 
    ->   object_id IN (2,3) AND 
    ->   date_event >= @dt1 AND 
    ->   date_event < @dt2 
    ->) A; 
+-----------+ 
| TotalTime | 
+-----------+ 
| 05:43:00 | 
+-----------+ 
1 row in set (0.00 sec) 

mysql> 

試試看!

+1

這裏令人印象深刻的工作。 – rncrtr 2013-05-03 22:40:29