我有存储事件的下一个表:(简化结构)
ID|用户|操作|时间戳
-|-|
12|user1|完|2022-01-01 05:00
43|user1|启动|2022-01-01 04:00
54|user1|完|2022-01-01 03:00
13|user1|开始|2022-01-01 02:00
我需要加入两个事件在一排,所以任何开始事件都伴随着结束事件在那之后。
因此,下一个结果应该是:
ID1|ID2|用户|开始时间戳|结束时间戳
-|
13|54|user1|2022-01-01 02:00|2022-01-01 03:00
43|12|user1|2022-01-01 04:00|2022-01-01 05:00
理想情况下,它不应该有太多的性能问题,因为表中可能有很多记录。
我尝试了下一个查询:
select
s.id as "ID1",
e.id as "ID2",
s.user,
s.time as "Start Time",
e.time as "End Time"
from Events s
left join Events e on s.user = e.user
where s.action = 'START'
and e.action = 'END'
and s.timestamp < e.timestamp
但它也会匹配记录13和记录12。可以只从左到右连接一次吗?(请记住,从时间上讲,IS应该是下一个结束记录?
谢谢
6条答案
按热度按时间zrfyljdw1#
我们希望为每个
START
事件获取最接近的END
事件的时间戳。我会采用以下方法:
1.获取每个
START
事件的最小值时间戳差异。1.现在使用
timedelta
查找实际的END
事件。假设
1.我们最多只能有一个尚未结束的活动!
1.对于每个
START
事件,时间戳将是唯一的。(END
事件也是如此。fcwjkofz2#
下面是一个使用横向联接的PostgreSQL解决方案。它可能正在HANA上工作,因为没有使用Postgres特定的功能。内部查询为在相应的“开始”之后最早出现的同一用户选择“结束”操作。已经开始但尚未完成的事件的“ID2”和“End Timestamp”的值将为空。
avwztpqn3#
您可以使用窗口函数Lead。
rqenqsqc4#
一种方法是横向联接,它选择大于“开始”时间戳的最小“结束”时间戳:
以上是标准的ANSI SQL,至少可以在postgres中使用。
在Postgres中,我将在
events ("user", "timestamp") where action = 'END'
上创建一个索引,以加快横向查询。sdnqo3pr5#
上面查询的问题是,对于每个开始事件,可以有多个结束事件,这些事件发生在之后。但是,您想要选择最接近开始事件的一个。您可以通过添加额外的聚合来实现这一点。
请找到HANA示例(不使用HANA特定功能):
如果需要包含
E.ID
,则需要将其重新连接到结果集。请注意,可能存在多个具有相同时间戳的结束事件,您需要在重新加入E.ID
时处理这些事件。如果您还想包括
START
事件而不包括相应的END
事件,则可以使用以下选项:tct7dpnv6#
在HANA SQL中测试的解决方案
相同的查询,但排除了不是最小持续时间的记录