首页 > 解决方案 > 订购事件数据

问题描述

我有一个包含事件数据的表。结构如下

CREATE TABLE t1 (`id` int, 
                 `start` datetime, 
                 `end` datetime default null, 
                 `evt` varchar(20), 
                 `sequence` int);

但事实证明,数据并非每次都以正确的顺序出现。正确的顺序由以下规则决定: 1. 每个事件都属于一个会话。您不能在 SessionStart、SessionEnd 之外有 EventStart、EventEnd。2. 每个会话都以SessionStart结尾SessionEnd。3. EventStart 不能晚于 EventEnd 出现。4. xStart, xEnd 使用开始时间匹配 5. 事件和会话的顺序由时间和顺序决定。

每一届都有很多活动EventStartEventEnd. 理想情况下,我们希望它们按以下顺序发生:

 1. SessionStart - 12 - 2018-02-10 15:50:00
 2. EventStart   -  0 - 2018-02-10 15:51:00
 3. EventEnd     -  2 - 2018-02-10 15:51:00 - 2018-02-10 15:52:00
 4. EventStart   -  0 - 2018-02-10 15:52:00
 5. EventEnd     -  3 - 2018-02-10 15:52:00 - 2018-02-10 15:53:00
 6. SessionEnd   - 13 - 2018-02-10 15:50:00 - 2018-02-10 15:55:00

但是如果我得到类似以下的东西怎么办

 1. EventStart   -  0 - 2018-02-10 15:51:00
 2. EventEnd     -  2 - 2018-02-10 15:51:00 - 2018-02-10 15:52:00
 3. EventStart   -  0 - 2018-02-10 15:52:00
 4. EventEnd     -  3 - 2018-02-10 15:52:00 - 2018-02-10 15:53:00
 5. SessionEnd   - 12 - 2018-02-10 15:50:00 - 2018-02-10 15:55:00
 6. SessionStart - 11 - 2018-02-10 15:50:00

我希望能够以正确的顺序收集多个会话。这可能使用单个查询吗?

https://www.db-fiddle.com/f/ipLSGJd5Pqzy1VBGXKx9Mv/2

标签: mysql

解决方案


这被证明是一个仅使用 SQL 来解决的难题,我最终做了很多更改。

我所做的是添加另一个名为 sessionId 的列。

CREATE TABLE t1 (`id` int, 
                 `start` datetime, 
                 `end` datetime default null, 
                 `sessionId` int,
                 `evt` varchar(20), 
                 `sequence` int);

此列由后台工作人员填充,并为会话期间内的每个事件分配相同的 sessionId。

然后我可以使用以下

SELECT * FROM t1 WHERE evt = 'SessionStart' AND sessionId = 1
UNION
SELECT * FROM t1 WHERE evt in('EventStart', 'EventEnd') AND sessionId = 1
UNION
SELECT * FROM t1 WHERE evt = 'SessionEnd' AND sessionId = 1

这可以进一步简化,因为生成事件的较新设备还将包括每个事件的事件生成时间戳和 sessionId。


推荐阅读