2016-05-31 67 views
1

我有一個具有以下字段的事件表:Mysql的解決方法窗函數

event_id 
event_type 
event_time 

給定一個時間D和一些k,我需要所有的event_type的是有超過K的計數在持續時間爲D的任何相對時間窗口中發生的事件。這基本上需要關於每個事件的滑動窗口。例如,我希望在任何10分鐘的持續時間內活動超過5個事件的所有event_type。

我不知道如何解決這個沒有窗口功能。

(我是在MySQL 5.6。我說的是在1萬行的數據集。)

回答

1

MySQL有沒有窗口功能的支持,但你可以使用相關子查詢中SELECT列表檢索一列:

SELECT 
    event_id, 
    event_type, 
    event_time, 
    (SELECT COUNT(*) FROM events EC WHERE EC.event_type = E.event_type AND EC.event_time > E.event_time) AS subsequent_event_count 
FROM 
    events E 
WHERE ... 

EXPLAIN它。在執行邏輯方面,這與SQL Server中的CROSS APPLY相同。

另一種方法是自連接:

SELECT 
    E.event_id, 
    E.event_type, 
    E.event_time, 
    COUNT(EC.event_id) AS subsequent_event_count 
FROM 
    events E 
    LEFT JOIN events EC 
    ON E.event_type = EC.event_type AND E.event_type < EC.event_type 
GROUP BY 
    E.event_id, 
    E.event_type, 
    E.event_time 

待辦事項測試這兩種方法的性能。

你可以做更多的創意加入,像

EC.event_time > E.event_time AND EC.event_time < E.event_time + INTERVAL 1 DAY 
-2

做CTE的工作速度不夠快?

WITH etypes_in_range AS (
SELECT tn.event_type, 
     count(1) AS num 
    FROM tablename tn 
WHERE tn.event_time < time_interval_end 
    AND tn.event_time > time_interval_start 
GROUP BY tn.event_type 
HAVING count(1) > 5) 
SELECT count(1) 
    FROM etypes_in_range 
+2

MySQL不與條款支持。 – Pred

1

編輯:重排的全部答案

現在我明白你的期望。

我創造了這樣一個測試表上我的MySQL,這似乎工作:

SELECT e2.event_type FROM events e1 
JOIN events e2 
    ON e1.event_time BETWEEN e2.event_time AND (e2.event_time + INTERVAL 10 MINUTE); 
GROUP BY e1.event_id, e2.event_type 
HAVING count(e2.event_type) >= 5 

基本上,每次自連接使用指定的相對時間窗口(從event_timeevent_time +窗口時間事件事件),然後通過e1even_id進行分組以獲得模擬的浮動時間窗口。此外,我們在這裏因event_type而煩惱,因爲您想要爲每個窗口獲取此字段值。

所有你需要考慮的是性能。我不確定它是否足夠有效1M記錄。

+0

時間範圍不是靜態的。這是相對每個事件。 @dragoste – smartnut007

+0

那麼,你說*指定*。我以爲指定是指定的,而不是相對的。 ;-) –

+0

同意。我用更多的說明更新了我的問題。 @dragoste – smartnut007