You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何查询符合条件事件前后2分钟内的所有关联事件?

问题

我可以编写查询语句返回符合特定条件的事件,但能否进一步查询原查询返回的每个事件的timestamp前后2分钟内的所有事件?

例如,我的数据库中有如下事件数据:

SELECT Id,Name,StartDateTime,Length FROM Events ORDER BY StartDateTime DESC;

查询结果:

+--------+--------------+---------------------+--------+
| Id     | Name         | StartDateTime       | Length |
+--------+--------------+---------------------+--------+
| 256779 | Event-256779 | 2024-07-22 16:08:43 |  16.51 |
| 256777 | Event-256777 | 2024-07-22 16:08:32 |  18.16 |
| 256775 | Event-256775 | 2024-07-22 16:05:55 |  10.88 |
| 256772 | Event-256772 | 2024-07-22 16:02:57 |  20.13 |
| 256770 | Event-256770 | 2024-07-22 16:02:51 |  15.73 |
| 256768 | Event-256768 | 2024-07-22 16:02:26 |  23.91 |
| 256767 | Event-256767 | 2024-07-22 16:00:34 |  17.82 |
| 256766 | Event-256766 | 2024-07-22 16:00:31 |   9.99 |
| 256765 | Event-256765 | 2024-07-22 15:59:57 |  19.46 |
| 256760 | Event-256760 | 2024-07-22 15:53:19 |  16.09 |
| 256758 | Event-256758 | 2024-07-22 15:53:15 |  11.56 |
| 256753 | Event-256753 | 2024-07-22 15:38:37 |   8.72 |
| 256745 | Event-256745 | 2024-07-22 15:32:52 |  15.50 |
| 256744 | Event-256744 | 2024-07-22 15:32:51 |   6.51 |
| 256737 | Event-256737 | 2024-07-22 15:11:06 |  19.93 |
| 256729 | Event-256729 | 2024-07-22 15:01:17 |   8.98 |
| 256724 | Event-256724 | 2024-07-22 14:54:34 |   9.45 |
| 256722 | Event-256722 | 2024-07-22 14:52:11 |  10.01 |
| 256721 | Event-256721 | 2024-07-22 14:52:09 |   8.83 |
| 256717 | Event-256717 | 2024-07-22 14:35:07 |  17.93 |
+--------+--------------+---------------------+--------+

我需要先查询所有Length小于10的事件,同时返回这些事件前后2分钟内的所有事件。初始查询语句如下:

SELECT Id,Name,StartDateTime,Length FROM Events WHERE Length < 10 ORDER BY StartDateTime DESC;

查询结果:

+--------+--------------+---------------------+--------+
| Id     | Name         | StartDateTime       | Length |
+--------+--------------+---------------------+--------+
| 256766 | Event-256766 | 2024-07-22 16:00:31 |   9.99 |
| 256753 | Event-256753 | 2024-07-22 15:38:37 |   8.72 |
| 256744 | Event-256744 | 2024-07-22 15:32:51 |   6.51 |
| 256729 | Event-256729 | 2024-07-22 15:01:17 |   8.98 |
| 256724 | Event-256724 | 2024-07-22 14:54:34 |   9.45 |
| 256721 | Event-256721 | 2024-07-22 14:52:09 |   8.83 |
+--------+--------------+---------------------+--------+

期望得到的查询结果如下:

+--------+--------------+---------------------+--------+
| Id     | Name         | StartDateTime       | Length |
+--------+--------------+---------------------+--------+
| 256767 | Event-256767 | 2024-07-22 16:00:34 |  17.82 |
| 256766 | Event-256766 | 2024-07-22 16:00:31 |   9.99 |
| 256765 | Event-256765 | 2024-07-22 15:59:57 |  19.46 |
| 256753 | Event-256753 | 2024-07-22 15:38:37 |   8.72 |
| 256745 | Event-256745 | 2024-07-22 15:32:52 |  15.50 |
| 256744 | Event-256744 | 2024-07-22 15:32:51 |   6.51 |
| 256729 | Event-256729 | 2024-07-22 15:01:17 |   8.98 |
| 256724 | Event-256724 | 2024-07-22 14:54:34 |   9.45 |
| 256722 | Event-256722 | 2024-07-22 14:52:11 |  10.01 |
| 256721 | Event-256721 | 2024-07-22 14:52:09 |   8.83 |
+--------+--------------+---------------------+--------+

解决方案

方法1:子查询+时间范围匹配

通过子查询获取所有Length<10的事件的时间范围,然后匹配所有落在这些事件前后2分钟内的记录,用DISTINCT避免重复(如果某事件同时属于多个目标事件的时间范围):

SELECT DISTINCT e.Id, e.Name, e.StartDateTime, e.Length
FROM Events e
WHERE EXISTS (
    SELECT 1
    FROM Events filter_e
    WHERE filter_e.Length < 10
    AND e.StartDateTime BETWEEN 
        DATE_SUB(filter_e.StartDateTime, INTERVAL 2 MINUTE) 
        AND DATE_ADD(filter_e.StartDateTime, INTERVAL 2 MINUTE)
)
ORDER BY e.StartDateTime DESC;

方法2:JOIN关联查询

将原表与筛选出的短事件表做关联,匹配时间在目标事件前后2分钟内的记录,同样用DISTINCT去重:

SELECT DISTINCT e.Id, e.Name, e.StartDateTime, e.Length
FROM Events e
JOIN Events filter_e ON 
    e.StartDateTime BETWEEN 
        DATE_SUB(filter_e.StartDateTime, INTERVAL 2 MINUTE) 
        AND DATE_ADD(filter_e.StartDateTime, INTERVAL 2 MINUTE)
WHERE filter_e.Length < 10
ORDER BY e.StartDateTime DESC;

方法3:窗口函数(适用于MySQL 8+、PostgreSQL等)

利用窗口函数在时间范围内查找是否存在Length<10的事件,然后筛选出符合条件的记录:

WITH event_with_context AS (
    SELECT 
        Id, Name, StartDateTime, Length,
        MAX(CASE WHEN Length < 10 THEN 1 ELSE 0 END) OVER (
            ORDER BY StartDateTime
            RANGE BETWEEN INTERVAL 2 MINUTE PRECEDING AND INTERVAL 2 MINUTE FOLLOWING
        ) AS has_short_event
    FROM Events
)
SELECT Id, Name, StartDateTime, Length
FROM event_with_context
WHERE has_short_event = 1
ORDER BY StartDateTime DESC;

以上三种方法都能得到你期望的结果,可根据你的数据库版本和性能需求选择合适的方案。

内容的提问来源于stack exchange,提问作者Simpler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 15:54:54