2010-11-06 36 views
3

我正在寫一個查詢,它將從日誌表中獲取結果,從而概述有多少訪問者登錄了我網頁以指定的時間間隔,考慮到他們的實際登錄時間(login_time,logout_time)和輸入的GROUP by參數。 (DAY(),HOUR()或MINUTE())MySQL查詢基於輸入時間間隔的GROUP BY和COUNT +考慮到兩個表列作爲區間

我已經扭轉了我的大腦在這個幾天的開關。真的需要一些有興趣的人的正面意見。

輸入

所以basicly什麼,我會在我的查詢輸入將是我想通過搜索什麼時間間隔。指定結果如何分組。 (DAY(),HOUR()或MINUTE())

實施例數據

ID| userID | login_time   | logout_time 
------------------------------------------------------ 
1 | 1  | 06.11.2010 16:57:16 | 06.11.2010 16:34:11 
2 | 2  | 06.11.2010 16:47:11 | 06.11.2010 19:55:15 
3 | 3  | 06.11.2010 16:33:16 | 06.11.2010 16:53:33 
4 | 4  | 06.11.2010 16:13:25 | 06.11.2010 18:54:54 
5 | 5  | 06.11.2010 16:02:16 | 06.11.2010 16:34:11 
6 | 6  | 06.11.2010 16:00:11 | 06.11.2010 17:55:19 
7 | 6  | 06.11.2010 19:00:11 | 06.11.2010 22:55:19 
8 | 6  | 06.11.2010 20:00:11 | 06.11.2010 23:55:19 
9 | 6  | 06.11.2010 20:00:11 | 06.11.2010 21:55:19 
9 | 6  | 06.11.2010 09:00:11 | 06.11.2010 10:00:19 

首選結果

示例輸入:2010年6月11日之間十六點三十分00秒和06.11.2010 16:35:00和分組由MINUTE()

Count | Date 
--------------------------- 
5  | 06.11.2010 16:30:00 
5  | 06.11.2010 16:31:00 
5  | 06.11.2010 16:32:00 
4  | 06.11.2010 16:33:00 
5  | 06.11.2010 16:34:00 
3  | 06.11.2010 16:35:00 

示例輸入:2010年6月11日00:30:00和2010年6月11日之間23時三十五分00秒和HOUR分組()

Count | Date 
--------------------------- 
1  | 06.11.2010 09:00:00 
1  | 06.11.2010 10:00:00 

- > PS:我不如果有間隔缺失(例如,無數據)

6  | 06.11.2010 16:00:00 
3  | 06.11.2010 17:00:00 
2  | 06.11.2010 18:00:00 
2  | 06.11.2010 19:00:00 
3  | 06.11.2010 20:00:00 
3  | 06.11.2010 21:00:00 
2  | 06.11.2010 22:00:00 
1  | 06.11.2010 23:00:00 

也許你可以說明一個合適的,有效的查詢,將產生預期的結果我有什麼想法?暫時我不會將這些混亂的代碼從這篇文章中排除出去。

+1

如果允許多個步驟,這將是我的承擔。 1.創建一個包含MIN(login_time)和MAX(logout_time)之間所有分鐘的分鐘表。 2.在輸入表和INNER JOIN temptable ON temptable.datetime BETWEEN input.login_time AND input.logout_time之間創建一個INNER JOIN。 3.按可能的日期時間分組。 – 2010-11-06 18:32:41

回答

2

在SQL中執行此操作的最簡單方法是創建一個包含要測試的所有時間值的臨時表,然後將其加入到日誌表中。

drop table if exists minutes; 
create temporary table minutes (date datetime not null); 
set @t := '2010.11.06 16:30:00'; insert into minutes values (@t); 
set @t := @t + interval 1 minute; insert into minutes values (@t); 
set @t := @t + interval 1 minute; insert into minutes values (@t); 
set @t := @t + interval 1 minute; insert into minutes values (@t); 
set @t := @t + interval 1 minute; insert into minutes values (@t); 
set @t := @t + interval 1 minute; insert into minutes values (@t); 

select count(*) as count, m.date 
from minutes m join log l 
on m.date <= l.logout_time and m.date + interval 1 minute >= l.login_time 
group by m.date; 
+1

+1。我的思路似乎是一樣的。 – 2010-11-06 18:44:25

3

對不起,沒有辦法使用單個查詢。由於SQL基於集合論,因此您必須創建一組時間間隔。

您可以在臨時表中或存儲過程中執行此操作,該過程計算時間間隔併爲每個間隔執行查詢。

所以,你可以這樣做:

CREATE TEMPORARY TABLE temp_intervals (
    start_datetime DATETIME NOT NULL , 
    end_datetime DATETIME NOT NULL 
) 

INSERT INTO temp_intervals(start_datetime, end_datetime) VALUES 
    ('2010-11-06 16:30:00', '2010-11-06 16:31:00'), 
    ('2010-11-06 16:31:00', '2010-11-06 16:32:00') 
    ... 

然後執行查詢:

SELECT start_datetime, COUNT(*) 
FROM temp_intervals 
LEFT JOIN login_history -- LEFT JOIN if you want empty intervals in the result 
WHERE login_time <= start_datetime AND logout_time > end_datetime 
GROUP BY start_datetime 

請記住,所有的語句在一個連接來完成,因爲臨時表是隻對連接可見。

此外,您不需要任何過程語言,因爲您可以讓MySQL使用存儲過程創建臨時表。

+1

+1你幾分鐘後第一次,但直到我幾乎準備好發佈我的答案時,我的顯示屏纔會更新。 – 2010-11-06 18:59:28

+0

出色的策略,輕鬆適應。 – 2013-02-18 22:25:07