SQL会从时间序列数据中过滤符合特定条件的记录

时间:2019-06-18 10:15:53

标签: sql presto

有一个表,其中存储了以下视频观看日志的数据。

|user_id| status |     time         |
-------------------------------------
|user_a |start   |2019-06-18 00:00:00|
|user_a |progress|2019-06-18 00:00:05|
|user_a |progress|2019-06-18 00:00:10|
|user_a |complete|2019-06-18 00:00:15|
|user_a |start   |2019-06-18 00:10:00|
|user_a |complete|2019-06-18 00:10:05|
|user_b |start   |2019-06-18 00:20:00|
|user_b |progress|2019-06-18 00:20:05|
|user_b |progress|2019-06-18 00:20:10|

“开始”是视频观看开始标记, “进度”是视频观看标志,并且 “完成”是视频观看完成标记。

由于可能无法观看视频,因此未始终设置完成标志。

但是,在某些情况下,可能未设置完成标志。

我要从上面的数据记录中排除只有开始和完成(没有进度)的数据。

具体来说,我想排除以下记录。

|user_a |start   |2019-06-18 00:10:00|
|user_a |complete|2019-06-18 00:10:05|

是否可以使用sql做到这一点?

2 个答案:

答案 0 :(得分:1)

您可以使用lead()lag()窗口分析功能:

select user_id, status, time 
  from
  (
   select lag(status,1,'x') over (order by time) lg,
          lead(status,1,'x') over (order by time) ld,
          t.*
     from t
   ) t2
 where not ( lg = ld and status in ('start','complete')) 

我在SQL Server DB

的小提琴中显示了 Demo

答案 1 :(得分:1)

您可以使用lead()lag()

select *
from (select t.*,
             lag(status) over (partition by user_id order by time) as prev_status,
             lead(status) over (partition by user_id order by time) as next_status
      from t
     ) t
where not ((status = 'start' and next_status = 'complete') or
           (status = 'complete' and prev_status = 'start')
          );

或者,给定样本数据,您可以使用:

where 'progress' in (prev_status, status, next_status);