我有一个包含以下字段的事件表:
event_id
event_type
event_time
如果持续时间D
和数字k
,我需要计算在任何相对时间窗口内有超过event_type
个事件的所有K
个持续时间D
。这基本上需要关于每个事件的滑动窗口。例如,我想要在任何10分钟的持续时间内活动超过5个事件的所有event_type。
我不知道如何在没有窗口功能的情况下解决这个问题。
(我在mysql 5.6上。我说的是一个不到100万行的数据集。)
答案 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_time
到event_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