用于窗口函数的Mysql变通方法

时间:2016-05-31 06:29:14

标签: mysql sql

我有一个包含以下字段的事件表:

event_id
event_type 
event_time

如果持续时间D和数字k,我需要计算在任何相对时间窗口内有超过event_type个事件的所有K个持续时间D。这基本上需要关于每个事件的滑动窗口。例如,我想要在任何10分钟的持续时间内活动超过5个事件的所有event_type。

我不知道如何在没有窗口功能的情况下解决这个问题。

(我在mysql 5.6上。我说的是一个不到100万行的数据集。)

4 个答案:

答案 0 :(得分:3)

MySQL没有窗口函数支持,但您可以使用/// <summary> /// Description what the class does /// </summary> public class MyClass { /// <summary> /// Description what the function does /// </summary> /// <param name="param1">Description what the parameter does /// Optional tags inside param1: /// <c></c> <code></code> <list type=""></list> <paramref name="param1"/> /// <para></para> /// </param> /// <param name="param2">Description what the parameter does</param> /// <returns>Description about the return value</returns> public string MyMethod(int param1, string param2) { return "Some value: " + MyProperty; } /// <summary> /// Description what the property does /// </summary> /// <see cref="MyMethod(int, string)"/> string MyProperty { get; set; } // optional tags (valid for class and methods): /// <completionlist cref=""/> /// <example></example> /// <exception cref=""></exception> /// <include file='' path='[@name=""]'/> /// <permission cref=""></permission> /// <remarks></remarks> /// <see cref=""/> /// <seealso cref=""/> } 列表中的相关子查询来检索一列:

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 ... 它。这在执行逻辑方面与SQL Server中的EXPLAIN相同。

另一种方法是自我加入:

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

答案 1 :(得分: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 +窗口持续时间),然后按 e1 分组even_id获取模拟的浮动时间窗口。此外,我们在此处event_type感到厌烦,因为您希望为每个窗口获取此字段值。

你需要思考的只是表现。我不确定它对于1M的记录是否足够有效。

答案 2 :(得分:0)

Notice that this lack of functionality is a thing of the past with MySQL 8 and later: https://dev.mysql.com/doc/refman/8.0/en/window-functions.html

答案 3 :(得分:-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