Kullanıcılarımızın, iPad uygulamasında bir tablo üzerinde yaptıkları işlemlerin ana akışlarını günlüğe kaydediyoruz. Her bir akışın bir başlangıç (etiketli Başlangıç) ve İptal Edilen veya Bitirilmiş bir ucu vardır ve herhangi bir örtüşen olay olmamalıdır.Postgresql'de Sıralı Olayların Eşleştirilmesi
bir kullanıcı için Başlatılan İptal veya Biten akışlarının kümesi aşağıdaki gibidir:
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
Biz ne kadar iptal edilen ve bitmiş akışına son ortalama hesaplamak istiyorum. Bunun için İptal Edilen veya Tamamlanmış ile başlatılan etkinliği eşleştirmeliyiz. Flow1 (süregelen akışını sonlandırmadan önce
bir müşteri yeni akışını başlatmak istiyor(en Flow2 diyelim): Aşağıdaki kod ancak elimizdeki aşağıdaki veri kalitesi soruna geçici edemez gelmez ki), yeni akış için başlatılan etkinliği çekerken iptal edilmiş bir etkinlik çekiyoruz. Yani
Flow1 Cancelled=Flow2 Started
. Ancak, aslında farklı akışlara ait olan sıralı olaylar arasında sıralamak/yönlendirmek/yönlendirmek için pencere işlevlerini kullandığımızda. Bu kodu kullanarak :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
Bu sonuç almak:
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
Ama biz bu almalısınız: Öyle kodu değiştiremez gerekiyor Nasıl
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
eşleştirme doğru mu?
Çalışıyor! Oldukça şık bir çözüm ... teşekkürler! –