我在Hive中有一张表: dt(timestamp),event_id(string)
我正在寻找在同一会话中发生在(例如)一天内发生的所有事件。假设单个会话可以跨越多天。
session dt event_id
1 2016-06-10 00:07:33 u38443jdnksdjoeoewk
2 2016-06-11 11:11:41 u39839jdijewenkfjij
1 2016-06-15 13:07:42 u38443jdjdksdnlqpma
2 2016-06-12 05:08:07 u38443jmcmsdjwewekh
在这种情况下,结果集将是
2016-06-11 11:11:41 u39839jdijewenkfjij
2016-06-12 05:08:07 u38443jmcmsdjwewekh
因为其他行的时间戳超过了一天。这似乎可以通过自联接来实现,但这将非常昂贵。还有更好的方法吗?
答案 0 :(得分:1)
使用lag
和lead
获取上一行和下一行的日期,并用当前行的日期减去它。检查它们中的任何一个是否在当前行日期的一天内。
select session,dt,event_id
from (
select dt,event_id,session,
unix_timestamp(dt)-unix_timestamp(lag(dt) over(partition by session order by dt)) prev_diff,
unix_timestamp(lead(dt) over(partition by session order by dt))-unix_timestamp(dt) next_diff
from t
) x
where prev_diff <= 86400 or next_diff <= 86400
答案 1 :(得分:1)
在任何给定的一天内获得所有事件的最佳方法是使用自我加入。在计算上,它不会那么昂贵。我在一张有7000条记录的桌子上进行了测试,当在正负60分钟进行匹配时,需要3秒钟,然后返回176,588条结果。我使用DATEDIFF进行比较,或者您可以使用DATEADD并比较两个限制。以下是使用您的表格的两个示例:
SELECT h1.session, h1.event_id, h2.session, h2.event_id, h1.dt, h2.dt
FROM Hive h1
JOIN Hive h2 ON DATEDIFF(hh, h1.dt, h2.dt) < 24
SELECT h1.session, h1.event_id, h2.session, h2.event_id, h1.dt, h2.dt
FROM Hive h1
JOIN Hive h2 ON DATEADD(d,1,h1.dt) >= h2.dt
AND DATEADD(d,-1,h1.dt) <= h2.dt