【问题标题】:need to find start and end time of events which is still not active需要找到仍然不活跃的事件的开始和结束时间
【发布时间】:2021-04-09 06:15:26
【问题描述】:

我有一个带有 3 coulmne timestamp eventid active 的表

timestamp eventid active
2020-02-01 22:44:23 E1 true
2020-02-01 22:45:23 E1 false
2020-02-01 22:46:23 E1 true
2020-02-01 22:47:23 E1 false
2020-02-01 22:44:23 E2 true
2020-02-01 22:45:23 E2 false
2020-02-01 22:46:23 E2 true

需要找到事件的开始和结束时间 此处的事件 e2 不会被视为仍处于活动状态。

Start_Time End_Time eventid
2020-02-01 22:44:23 2020-02-01 22:47:23 E1

更新: 能够使用 Pyspark 找到解决方案,请参阅下面的答案

【问题讨论】:

  • 编辑您的问题并显示您想要的结果。同时标记您正在使用的数据库。
  • @Grdon 更新了问题,关于数据库,我正在研究 spark sql,但任何通用 sql(任何数据库)都可以使用

标签: sql apache-spark-sql time-series


【解决方案1】:
 ;WITH cte AS
(
   SELECT *,
         ROW_NUMBER() OVER (PARTITION BY eventid ORDER BY timestamp DESC) AS rn
   FROM yourTable
)
SELECT min(yt.timestamp) as Start_Time, max(yt.timestamp) as End_Time,yt.eventid
FROM yourTable yt
inner join cte
On cte.eventid=yt.eventid
WHERE 
cte.rn = 1 and cte.active="false"
group by yt.eventid

这样你就看不到E2了,因为它还处于活动状态。

【讨论】:

  • max(timestamp) 怎么可能返回 false?
  • 时间戳的数据类型不是布尔值。所以 max(timestamp) 将返回一个时间戳,而不是 true 或 false。
  • 我不确定我是否完全遵循了它,但据我所知,“cte.rn = 1 and cte.active="false"" 将成为我猜想的一切。所以不确定
  • 你可以试试看,你想要的。当 cte.rn=1 且 cte.active ="false" 表示关闭。所以只有“不活跃”的结果会与其他表连接。
【解决方案2】:

使用 Lead 功能,我能够找到完整的事件。

window = Window.partitionBy('eventid').orderBy('timestamp')
eventWithLead = dataFrame.withColumn('endtime',lead(col('timestamp'), 1).over(window))\
                         .withColumn('nextstatus',lead(col('active'), 1).over(window))\
                         .select('eventid', 'active','endtime', 'timestamp', 'nextstatus')
   
openEvents = eventWithLead.select('eventId').filter(col('active')==True)\
                                            .filter(col('nextstatus').isNull())

errorWithLeadFinal = eventWithLead\
                         .join(openEvents, on=['eventid'], how='left_anti')
                         .filter(col('active')!= False)
                         .filter(col('nextstatus')!= True)

【讨论】:

    【解决方案3】:

    这是你想要的吗?

    select eventid, min(timestamp) as starttime, max(timestamp) as endtime
    from t
    group by eventid
    having max(case when active = 'true' then timestamp else 0 end) = max(timestamp);
    

    这会返回在最近时间戳上处于活动状态的事件。

    【讨论】:

    • @Grondon,感谢您的回答,但我猜想计算时间戳的总和无济于事
    • @MakeitEasy 。 . .那应该是max() 而不是sum()。我修好了。
    猜你喜欢
    • 1970-01-01
    • 2020-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 2013-01-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多