gpt4 book ai didi

mysql - 通过比较前后记录创建自定义 session 标识符

转载 作者:太空宇宙 更新时间:2023-11-03 10:35:51 25 4
gpt4 key购买 nike

我正在尝试基于数据创建一些 session (在 Vertica 中,但任何其他 OLAP 数据库 SQL 都应该有效)

我有一个简单的表,包含名为 Vehicle-ID、Event、Event-Code 的列,“Session-ID”是我要填充的列

我尝试过分区、领先、滞后和其他分析功能,但没有成功。 session的创建逻辑如下。

session 在您第一次遇到启动事件 ( 1 ) 时开始,并在获得最后一个停止 (2) 事件时结束。正如您在 session 开始后在 session 中看到的那样,如果我们得到更多的开始事件,我们将忽略并寻找最后停止事件。示例 Session-Id-1

由于某种原因,在停止事件之后,下一个事件没有开始(即运行等),这意味着它是一个糟糕的 session ,我们想要捕获这个糟糕的 session ,直到我们找到一个新的开始。例子在session-id-2

我正在尝试使用 lead 和 lag 创建标记,它们查看前后的记录,并添加标记,如 first_start、final_end 等 .. 但它变得笨拙

更新 SQL 查询以创建 session

SELECT * , SUM(FLAG) OVER ( PARTITION BY Vehicle_ID ORDER BY Event_Time ROWS UNBOUNDED PRECEDING) AS SESSION_ID
FROM (
SELECT * ,
Case when Prev_Start_time < Prev_Stop_time and Event != 'Started' Then 1 else 0 end as bad_data ,
Case when
( Event = 'Started' and Prev_Start_time < Prev_Stop_time ) OR
--( Event = 'Stopped' and Prev_Event = 'Stopped' ) OR
( Event = 'Running' and Prev_Start_time < Prev_Stop_time) OR
( Prev_Event IS NULL)
THEN 1 END AS FLAG
--Case when ( Event = 'Stopped' and Next_Event = 'Stopped' ) OR ( Event != 'Started' and Prev_Start_time < Prev_Stop_time) OR ( Prev_Event IS NULL) THEN 1 END AS FLAG
FROM (
WITH
input(Vehicle_ID,Event_time,Event,Event_Code) AS (
SELECT 1,TIME '09:01:00','Started',1
UNION ALL SELECT 1,TIME '09:02:00','Started',1
UNION ALL SELECT 1,TIME '09:03:00','Running',3
UNION ALL SELECT 1,TIME '09:04:00','Started',1
UNION ALL SELECT 1,TIME '09:05:00','Running',3
UNION ALL SELECT 1,TIME '09:06:00','Running',3
UNION ALL SELECT 1,TIME '09:07:00','Running',3
UNION ALL SELECT 1,TIME '09:08:00','Stopped',2
UNION ALL SELECT 1,TIME '09:09:00','Stopped',2
UNION ALL SELECT 1,TIME '09:10:00','Running',3
UNION ALL SELECT 1,TIME '09:11:00','Running',3
UNION ALL SELECT 1,TIME '09:12:00','Running',3
UNION ALL SELECT 1,TIME '09:13:00','Started',1
UNION ALL SELECT 1,TIME '09:14:00','Started',1
UNION ALL SELECT 1,TIME '09:15:00','Running',3
UNION ALL SELECT 1,TIME '09:16:00','Started',1
UNION ALL SELECT 1,TIME '09:17:00','Running',3
UNION ALL SELECT 1,TIME '09:18:00','Running',3
UNION ALL SELECT 1,TIME '09:19:00','Running',3
UNION ALL SELECT 1,TIME '09:20:00','Stopped',2
UNION ALL SELECT 1,TIME '09:21:00','Started',1
UNION ALL SELECT 1,TIME '09:22:00','Started',1
UNION ALL SELECT 1,TIME '09:23:00','Running',3
UNION ALL SELECT 1,TIME '09:24:00','Started',1
UNION ALL SELECT 1,TIME '09:25:00','Running',3
UNION ALL SELECT 1,TIME '09:26:00','Running',3
UNION ALL SELECT 1,TIME '09:27:00','Running',3
UNION ALL SELECT 1,TIME '09:28:00','Stopped',2
)
SELECT *,
Max( Case Event when 'Started' then Event_time end ) OVER (PARTITION BY Vehicle_ID ORDER BY Event_time Rows between unbounded preceding and 1 preceding ) AS Prev_Start_time,
Max( Case Event when 'Stopped' then Event_time end ) OVER (PARTITION BY Vehicle_ID ORDER BY Event_time Rows between unbounded preceding and 1 preceding ) AS Prev_Stop_time,
LAG(Event) OVER (PARTITION BY Vehicle_ID ORDER BY Event_time ) AS Prev_Event,
LEAD(Event) OVER (PARTITION BY Vehicle_ID ORDER BY Event_time ) AS Next_Event
FROM input ) AS T1
) AS T2

根据更新的查询新输入

Vehicle_ID  Event_time      Event       Event_Code  Prev_Start_time Prev_Stop_time      Prev_Event      Next_Event      bad_data    FLAG        SESSION_ID
1 9:01:00 Started 1 NULL NULL NULL Started 0 1 1
1 9:02:00 Started 1 9:01:00 NULL Started Running 0 NULL 1
1 9:03:00 Running 3 9:02:00 NULL Started Started 0 NULL 1
1 9:04:00 Started 1 9:02:00 NULL Running Running 0 NULL 1
1 9:05:00 Running 3 9:04:00 NULL Started Running 0 NULL 1
1 9:06:00 Running 3 9:04:00 NULL Running Running 0 NULL 1
1 9:07:00 Running 3 9:04:00 NULL Running Stopped 0 NULL 1
1 9:08:00 Stopped 2 9:04:00 NULL Running Stopped 0 NULL 1
1 9:09:00 Stopped 2 9:04:00 9:08:00 Stopped Running 1 NULL 1
1 9:10:00 Running 3 9:04:00 9:09:00 Stopped Running 1 1 2
1 9:11:00 Running 3 9:04:00 9:09:00 Running Running 1 1 3
1 9:12:00 Running 3 9:04:00 9:09:00 Running Started 1 1 4
1 9:13:00 Started 1 9:04:00 9:09:00 Running Started 0 1 5
1 9:14:00 Started 1 9:13:00 9:09:00 Started Running 0 NULL 5
1 9:15:00 Running 3 9:14:00 9:09:00 Started Started 0 NULL 5
1 9:16:00 Started 1 9:14:00 9:09:00 Running Running 0 NULL 5
1 9:17:00 Running 3 9:16:00 9:09:00 Started Running 0 NULL 5
1 9:18:00 Running 3 9:16:00 9:09:00 Running Running 0 NULL 5
1 9:19:00 Running 3 9:16:00 9:09:00 Running Stopped 0 NULL 5
1 9:20:00 Stopped 2 9:16:00 9:09:00 Running Started 0 NULL 5
1 9:21:00 Started 1 9:16:00 9:20:00 Stopped Started 0 1 6
1 9:22:00 Started 1 9:21:00 9:20:00 Started Running 0 NULL 6
1 9:23:00 Running 3 9:22:00 9:20:00 Started Started 0 NULL 6
1 9:24:00 Started 1 9:22:00 9:20:00 Running Running 0 NULL 6
1 9:25:00 Running 3 9:24:00 9:20:00 Started Running 0 NULL 6
1 9:26:00 Running 3 9:24:00 9:20:00 Running Running 0 NULL 6
1 9:27:00 Running 3 9:24:00 9:20:00 Running Stopped 0 NULL 6
1 9:28:00 Stopped 2 9:24:00 9:20:00 Running NULL 0 NULL 6

最佳答案

在 Vertica 中,我会使用 MATCH() 子句。它还会遗漏不需要的行 - 那些没有意义的“运行”。试试这个:

    WITH
-- your input as you gave it
input(tm,Vehicle_ID,Col1,Event,Event_Code,Session_ID) AS (
SELECT TIME '09:01:00',1,'A','Started',1,1
UNION ALL SELECT TIME '09:02:00',1,'B','Started',1,1
UNION ALL SELECT TIME '09:03:00',1,'C','Running',3,1
UNION ALL SELECT TIME '09:04:00',1,'A','Started',1,1
UNION ALL SELECT TIME '09:05:00',1,'B','Running',3,1
UNION ALL SELECT TIME '09:06:00',1,'C','Running',3,1
UNION ALL SELECT TIME '09:07:00',1,'A','Running',3,1
UNION ALL SELECT TIME '09:08:00',1,'A','Stopped',2,1
UNION ALL SELECT TIME '09:09:00',1,'B','Stopped',2,1
UNION ALL SELECT TIME '09:10:00',1,'C','Running',3,2
UNION ALL SELECT TIME '09:11:00',1,'A','Running',3,2
UNION ALL SELECT TIME '09:12:00',1,'B','Running',3,2
UNION ALL SELECT TIME '09:13:00',1,'A','Started',1,3
UNION ALL SELECT TIME '09:14:00',1,'B','Started',1,3
UNION ALL SELECT TIME '09:15:00',1,'C','Running',3,3
UNION ALL SELECT TIME '09:16:00',1,'A','Started',1,3
UNION ALL SELECT TIME '09:17:00',1,'B','Running',3,3
UNION ALL SELECT TIME '09:18:00',1,'C','Running',3,3
UNION ALL SELECT TIME '09:19:00',1,'A','Running',3,3
UNION ALL SELECT TIME '09:20:00',1,'A','Stopped',2,3
)
-- here is where the real select starts ..
SELECT
pattern_id()
, match_id()
, event_name()
, *
FROM input
MATCH(
PARTITION BY vehicle_id
ORDER BY tm
DEFINE
started_event AS (event='Started')
, running_event AS (event='Running')
, stopped_event AS (event='Stopped')
PATTERN p AS (started_event+ (running_event|started_event)* stopped_event+)
)
;


pattern_id|match_id|event_name |tm |Vehicle_ID|Col1|Event |Event_Code|Session_ID
1| 1|started_event|09:01:00| 1|A |Started| 1| 1
1| 2|started_event|09:02:00| 1|B |Started| 1| 1
1| 3|running_event|09:03:00| 1|C |Running| 3| 1
1| 4|started_event|09:04:00| 1|A |Started| 1| 1
1| 5|running_event|09:05:00| 1|B |Running| 3| 1
1| 6|running_event|09:06:00| 1|C |Running| 3| 1
1| 7|running_event|09:07:00| 1|A |Running| 3| 1
1| 8|stopped_event|09:08:00| 1|A |Stopped| 2| 1
1| 9|stopped_event|09:09:00| 1|B |Stopped| 2| 1
2| 1|started_event|09:13:00| 1|A |Started| 1| 3
2| 2|started_event|09:14:00| 1|B |Started| 1| 3
2| 3|running_event|09:15:00| 1|C |Running| 3| 3
2| 4|started_event|09:16:00| 1|A |Started| 1| 3
2| 5|running_event|09:17:00| 1|B |Running| 3| 3
2| 6|running_event|09:18:00| 1|C |Running| 3| 3
2| 7|running_event|09:19:00| 1|A |Running| 3| 3

关于mysql - 通过比较前后记录创建自定义 session 标识符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48590572/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com