Mysql窗口函数的解决方法

标签 mysql sql

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

event_id
event_type 
event_time

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

我不确定如何在没有窗口函数的情况下解决这个问题。

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

最佳答案

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

关于Mysql窗口函数的解决方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37538350/

相关文章:

sql - WHERE 子句中的 Oracle SQL 函数比 SELECT 子句中的运行时间更长

mysql - SQL 命令默认值

java - 使用 "StringUtils.join(array, "' ,'") 进行选择;"

php - 使用 PHP 和 MySQL 在 map 上绘制点

php - 如何使用 PHP 和/或 MySQL 清理美国地址格式

java - 使用具有 long 值的 java.sql.Date 构造函数

.net - IP 更改后重新连接已删除的 SqlConnection,而不回滚事务

sql - 选择具有两个字段的范围

mysql - TomEE 和 MySql - 查询不返回任何结果

mysql - 从一列获取 MAX 值,从另一列获取 MIN