2016-11-28 5 views
5

사용자가 iPad 앱에서 테이블에 대해 수행하는 주요 작업 흐름을 기록합니다. 각 흐름에는 시작 (시작됨으로 태그가 지정됨)과 태그가 취소됨 또는 완료 됨으로 끝나며 겹치는 이벤트가 없어야합니다.PostgreSQL의 순차적 이벤트 페어링

사용자에 대해, 시작 취소 또는 완료 흐름의 설정은 다음과 같습니다

user_id    timestamp     event_text  event_num 
[email protected] 2016-10-30 00:08:00.966+00 Flow Started 0 
[email protected] 2016-10-30 00:08:15.58+00 Flow Cancelled 2 
[email protected] 2016-10-30 00:08:15.581+00 Flow Started 0 
[email protected] 2016-10-30 00:34:44.134+00 Flow Finished 1 
[email protected] 2016-10-30 00:42:26.102+00 Flow Started 0 
[email protected] 2016-10-30 00:42:49.276+00 Flow Cancelled 2 
[email protected] 2016-10-30 00:42:49.277+00 Flow Started 0 
[email protected] 2016-10-30 00:59:47.337+00 Flow Cancelled 2 
[email protected] 2016-10-30 00:59:47.337+00 Flow Started 0 
[email protected] 2016-10-30 00:59:47.928+00 Flow Cancelled 2 

우리는 얼마나 오래 취소 및 완료 흐름 마지막 평균적으로 계산합니다. 이를 위해 시작 이벤트 인 취소 또는 완료를 쌍으로 만들어야합니다. 유량 1 (지속적인 흐름을 종료하기 전에

고객이 새로운 흐름을 시작하고 싶어
  • (의이 Flow2를 부르 자) : 다음 코드는 그러나 우리가 가지고있는 다음과 같은 데이터 품질 문제를 해결 할 수 않는 것을), 우리는 새로운 흐름에 대해 시작된 이벤트를 촬영하면서 취소 된 이벤트를 쏜다. 그래서 Flow1 Cancelled=Flow2 Started. 그러나 창 함수를 사용하여 순서를 지정하고 서로 다른 흐름에 실제로 속하는 정렬 된 이벤트 사이에서 리드/래그가 일치 할 때. 이 코드를 사용하여 는 :

    WITH track_scf AS (SELECT user_id, timestamp, event_text, CASE WHEN event_text LIKE '%Started%' THEN 0 when event_text like '%Cancelled%' then 2 ELSE 1 END AS event_num FROM tracks ORDER BY 2, 4 desc) SELECT user_id, CASE WHEN event_num=0 then timestamp end as start,CASE WHEN LEAD(event_num, 1) OVER (PARTITION BY user_id ORDER BY timestamp,event_num) <> 0 THEN LEAD(timestamp, 1) OVER (PARTITION BY user_id ORDER BY timestamp,event_num) END as end, CASE WHEN LEAD(event_num, 1) OVER (PARTITION BY user_id ORDER BY timestamp,event_num) <> 0 THEN LEAD(event_num, 1) OVER (PARTITION BY user_id ORDER BY timestamp,event_num) END as action FROM track_scf 
    

우리는이 결과를 얻을 :

user_id    start      end       action 
[email protected] 2016-10-30 00:08:00.966+00 2016-10-30 00:08:15.58+00 2 
[email protected] 2016-10-30 00:08:15.581+00 2016-10-30 00:34:44.134+00 1 
[email protected] 2016-10-30 00:42:26.102+00 2016-10-30 00:42:49.276+00 2 
[email protected] 2016-10-30 00:42:49.277+00 NULL      NULL 
[email protected] 2016-10-30 00:59:47.337+00 2016-10-30 00:59:47.337+00 2 
[email protected] NULL      2016-10-30 00:59:47.928+00 2 

을하지만 우리는이 가야 : 내가 그렇게 코드를 변경해야 할 방법

user_id    start      end       action 
[email protected] 2016-10-30 00:08:00.966+00 2016-10-30 00:08:15.58+00 2 
[email protected] 2016-10-30 00:08:15.581+00 2016-10-30 00:34:44.134+00 1 
[email protected] 2016-10-30 00:42:26.102+00 2016-10-30 00:42:49.276+00 2 
[email protected] 2016-10-30 00:42:49.277+00 2016-10-30 00:59:47.337+00 2 
[email protected] 2016-10-30 00:59:47.337+00 2016-10-30 00:59:47.928+00 2 

을 페어링이 올바른지?

답변

2
select  user_id  
      ,"start"      
      ,"end"       
      ,"action" 

from  (select  user_id 
         ,timestamp     as "start" 
         ,lead (event_num) over w as "action" 
         ,lead ("timestamp") over w as "end" 
         ,event_num 

      from  tracks t 

      window  w as (partition by user_id order by "timestamp",event_num desc) 
      ) t 

where  t.event_num = 0 
; 
+0

작동합니다! 꽤 매끄러운 솔루션 .. 고마워요! –