-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathma_u_shaped.sql
92 lines (72 loc) · 2.97 KB
/
ma_u_shaped.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
with
base as (
select
customer_id,
session_id,
extractURLParameter(url, 'source') as source,
extractURLParameter(url, 'medium') as medium,
nullIf(extractURLParameter(url, 'campaign'), '') as campaign,
nullIf(extractURLParameter(url, 'content'), '') as content,
nullIf(extractURLParameter(url, 'term'), '') as term,
revenue,
--- adding event_index and flag whether it was revenue-generating event for further use
row_number() over (partition by customer_id, session_id order by timestamp) as event_index,
if(revenue > 0, true, false) as revenue_event,
timestamp
from {{ ref('marketing_dummy_data') }}
),
/* since we defined attribution window as a single session,
we will need to drop any events that occur after revenue-generating
event withing single session so they won't mess with calculations */
int_get_revenue_event_index as (
select
customer_id,
session_id,
event_index
from base
where revenue_event = true
),
--- self join to identify rows that should be included in calculation
int_get_flags_for_calculation as (
select
base.customer_id,
base.session_id,
base.source,
base.revenue,
count() over (partition by customer_id, session_id) as session_events_cnt,
base.event_index,
base.revenue_event,
if(int_get_revenue_event_index.event_index >= base.event_index, true, false) as calculation_event
from base
left join int_get_revenue_event_index
on int_get_revenue_event_index.customer_id = base.customer_id
and int_get_revenue_event_index.session_id = base.session_id
),
int_split_revenue_u_shape as (
select
customer_id,
session_id,
source,
multiIf(
event_index = 1 and revenue_event = true, 1.0, --- revenue shouldn't be split if purchase happens at start
session_events_cnt = 1, 1.0, --- if there's single event in session we attribute session revenue to it
session_events_cnt = 2, 0.5, --- if 2 events - we split evenly
event_index = 1, 0.4, --- if there are more than 2, we actually start attributing 40% to first event
revenue_event = true, 0.4, --- 40% to last event, leading to purchase
0.2 / nullIf(toFloat64(session_events_cnt - 2), 0) --- 20% split evenly among remaining in between
) as weight,
--- getting sessions total revenue for further split
sum(revenue) over (partition by customer_id, session_id) as session_revenue,
session_revenue * weight as u_revenue
from int_get_flags_for_calculation
where calculation_event = true
),
analytics_ma_u_shaped as (
select
source as marketing_channel,
round(sum(u_revenue), 2) as channel_revenue,
formatReadableQuantity(channel_revenue) as channel_revenue_fmt
from int_split_revenue_u_shape
group by 1
)
select * from analytics_ma_u_shaped