SQL
Mobile ticketing
Funnel Explorer
Funnel Explorer model for mobile ticketing.
source-preserved
Blocks
funnel_explorer.sql · 56 lines
inferred
-- models/funnel_explorer.sql
{{ config(materialized='view') }}
SELECT sessions.unique_session_id as session_id
, sessions.session_start AS session_start
, MIN(
CASE WHEN
{% condition action_1 %} events.action {% endcondition %}
THEN events.ts
ELSE NULL END
) as action_1_time
, MIN(
CASE WHEN
{% condition action_2 %} events.action {% endcondition %}
THEN events.ts
ELSE NULL END
) as action_2_time
, MIN(
CASE WHEN
{% condition action_3 %} events.action {% endcondition %}
THEN events.ts
ELSE NULL END
) as action_3_time
, MIN(
CASE WHEN
{% condition action_4 %} events.action {% endcondition %}
THEN events.ts
ELSE NULL END
) as action_4_time
FROM public.ts_user_base AS events
LEFT JOIN {{ ref('sessions') }} sessions
ON events.uid = sessions.user_id
AND timestamp 'epoch' + events.ts * interval '1 second' >= sessions.session_start
AND timestamp 'epoch' + events.ts * interval '1 second' < sessions.next_session_start
AND {% condition event_time %} sessions.session_start {% endcondition %}
WHERE {% condition event_time %} timestamp 'epoch' + events.ts * interval '1 second' {% endcondition %}
GROUP BY 1,2
# models/schema.yml
version: 2
models:
- name: funnel_explorer
columns:
- name: session_id
tests:
- unique
- not_null
- name: user_id
- name: action_1
- name: action_2
- name: action_3
- name: action_4
- name: event1_before_event2
- name: event2_before_event3
- name: event3_before_event4
Assumptions
- Each ${view.SQL_TABLE_NAME} was mapped to {{ ref('view') }}; confirm a dbt model exists for each referenced view.
- materialized='view' is the default; no persist hint found.
- schema.yml columns come from view dimensions; a primary_key dimension gets unique + not_null tests.
funnel_explorer.sql · 34 lines
source-preserved
validation: not checked
SELECT sessions.unique_session_id as session_id
, sessions.session_start AS session_start
, MIN(
CASE WHEN
{% condition action_1 %} events.action {% endcondition %}
THEN events.ts
ELSE NULL END
) as action_1_time
, MIN(
CASE WHEN
{% condition action_2 %} events.action {% endcondition %}
THEN events.ts
ELSE NULL END
) as action_2_time
, MIN(
CASE WHEN
{% condition action_3 %} events.action {% endcondition %}
THEN events.ts
ELSE NULL END
) as action_3_time
, MIN(
CASE WHEN
{% condition action_4 %} events.action {% endcondition %}
THEN events.ts
ELSE NULL END
) as action_4_time
FROM public.ts_user_base AS events
LEFT JOIN ${sessions.SQL_TABLE_NAME} sessions
ON events.uid = sessions.user_id
AND timestamp 'epoch' + events.ts * interval '1 second' >= sessions.session_start
AND timestamp 'epoch' + events.ts * interval '1 second' < sessions.next_session_start
AND {% condition event_time %} sessions.session_start {% endcondition %}
WHERE {% condition event_time %} timestamp 'epoch' + events.ts * interval '1 second' {% endcondition %}
GROUP BY 1,2
funnel_explorer.view.lkml · 152 lines
inferred
view: funnel_explorer {
derived_table: {
sql: SELECT sessions.unique_session_id as session_id
, sessions.session_start AS session_start
, MIN(
CASE WHEN
{% condition action_1 %} events.action {% endcondition %}
THEN events.ts
ELSE NULL END
) as action_1_time
, MIN(
CASE WHEN
{% condition action_2 %} events.action {% endcondition %}
THEN events.ts
ELSE NULL END
) as action_2_time
, MIN(
CASE WHEN
{% condition action_3 %} events.action {% endcondition %}
THEN events.ts
ELSE NULL END
) as action_3_time
, MIN(
CASE WHEN
{% condition action_4 %} events.action {% endcondition %}
THEN events.ts
ELSE NULL END
) as action_4_time
FROM public.ts_user_base AS events
LEFT JOIN ${sessions.SQL_TABLE_NAME} sessions
ON events.uid = sessions.user_id
AND timestamp 'epoch' + events.ts * interval '1 second' >= sessions.session_start
AND timestamp 'epoch' + events.ts * interval '1 second' < sessions.next_session_start
AND {% condition event_time %} sessions.session_start {% endcondition %}
WHERE {% condition event_time %} timestamp 'epoch' + events.ts * interval '1 second' {% endcondition %}
GROUP BY 1,2 ;;
}
dimension: session_id {
type: string
primary_key: yes
hidden: yes
sql: ${TABLE}.session_id ;;
}
dimension: user_id {
type: int
hidden: yes
sql: ${TABLE}.user_id ;;
}
dimension: action_1 {
type: time
hidden: yes
sql: ${TABLE}.action_1_time ;;
}
dimension: action_2 {
type: time
hidden: yes
sql: ${TABLE}.action_2_time ;;
}
dimension: action_3 {
type: time
hidden: yes
sql: ${TABLE}.action_3_time ;;
}
dimension: action_4 {
type: time
hidden: yes
sql: ${TABLE}.action_4_time ;;
}
dimension: event1_before_event2 {
type: yesno
hidden: yes
sql: ${TABLE}.action_1_time < ${TABLE}.action_2_time ;;
}
dimension: event2_before_event3 {
type: yesno
hidden: yes
sql: ${TABLE}.action_2_time < ${TABLE}.action_3_time ;;
}
dimension: event3_before_event4 {
type: yesno
hidden: yes
sql: ${TABLE}.action_3_time < ${TABLE}.action_4_time ;;
}
dimension_group: session_start {
type: time
timeframes: [time, date, raw]
sql: ${TABLE}.session_start ;;
}
measure: count_sessions {
type: count_distinct
drill_fields: [detail*]
sql: ${session_id} ;;
}
measure: count_sessions_event1 {
label: "Action 1"
type: count_distinct
filters: [action_1_time: "NOT NULL"]
drill_fields: [detail*]
sql: ${session_id} ;;
}
measure: count_sessions_event12 {
label: "Action 2"
description: "Only includes sessions which also completed event 1"
type: count_distinct
filters: [action_1_time: "NOT NULL"]
filters: [action_2_time: "NOT NULL"]
filters: [event1_before_event2: "True"]
drill_fields: [detail*]
sql: ${session_id} ;;
}
measure: count_sessions_event123 {
label: "Action 3"
description: "Only includes sessions which also completed actions 1 and 2"
type: count_distinct
filters: [action_1_time: "NOT NULL"]
filters: [action_2_time: "NOT NULL"]
filters: [action_3_time: "NOT NULL"]
filters: [event1_before_event2: "True"]
filters: [event2_before_event3: "True"]
drill_fields: [detail*]
sql: ${session_id} ;;
}
measure: count_sessions_event1234 {
label: "Action 4"
description: "Only includes sessions which also completed actions 1, 2 and 3"
type: count_distinct
filters: [action_1_time: "NOT NULL"]
filters: [action_2_time: "NOT NULL"]
filters: [action_3_time: "NOT NULL"]
filters: [action_4_time: "NOT NULL"]
filters: [event1_before_event2: "True"]
filters: [event2_before_event3: "True"]
filters: [event3_before_event4: "True"]
drill_fields: [detail*]
sql: ${session_id} ;;
}
}
funnel_explorer.view.lookml · 133 lines
source-preserved
- view: funnel_explorer
derived_table:
sql: SELECT sessions.unique_session_id as session_id
, sessions.session_start AS session_start
, MIN(
CASE WHEN
{% condition action_1 %} events.action {% endcondition %}
THEN events.ts
ELSE NULL END
) as action_1_time
, MIN(
CASE WHEN
{% condition action_2 %} events.action {% endcondition %}
THEN events.ts
ELSE NULL END
) as action_2_time
, MIN(
CASE WHEN
{% condition action_3 %} events.action {% endcondition %}
THEN events.ts
ELSE NULL END
) as action_3_time
, MIN(
CASE WHEN
{% condition action_4 %} events.action {% endcondition %}
THEN events.ts
ELSE NULL END
) as action_4_time
FROM public.ts_user_base AS events
LEFT JOIN ${sessions.SQL_TABLE_NAME} sessions
ON events.uid = sessions.user_id
AND timestamp 'epoch' + events.ts * interval '1 second' >= sessions.session_start
AND timestamp 'epoch' + events.ts * interval '1 second' < sessions.next_session_start
AND {% condition event_time %} sessions.session_start {% endcondition %}
WHERE {% condition event_time %} timestamp 'epoch' + events.ts * interval '1 second' {% endcondition %}
GROUP BY 1,2
fields:
- dimension: session_id
type: string
primary_key: true
hidden: true
sql: ${TABLE}.session_id
- dimension: user_id
type: int
hidden: true
sql: ${TABLE}.user_id
- dimension: action_1
type: time
hidden: true
sql: ${TABLE}.action_1_time
- dimension: action_2
type: time
hidden: true
sql: ${TABLE}.action_2_time
- dimension: action_3
type: time
hidden: true
sql: ${TABLE}.action_3_time
- dimension: action_4
type: time
hidden: true
sql: ${TABLE}.action_4_time
- dimension: event1_before_event2
type: yesno
hidden: true
sql: ${TABLE}.action_1_time < ${TABLE}.action_2_time
- dimension: event2_before_event3
type: yesno
hidden: true
sql: ${TABLE}.action_2_time < ${TABLE}.action_3_time
- dimension: event3_before_event4
type: yesno
hidden: true
sql: ${TABLE}.action_3_time < ${TABLE}.action_4_time
- dimension_group: session_start
type: time
timeframes:
- time
- date
- raw
sql: ${TABLE}.session_start
- measure: count_sessions
type: count_distinct
drill_fields:
- detail*
sql: ${session_id}
- measure: count_sessions_event1
type: count_distinct
label: Action 1
drill_fields:
- detail*
filters:
- action_1_time: NOT NULL
sql: ${session_id}
- measure: count_sessions_event12
type: count_distinct
label: Action 2
description: Only includes sessions which also completed event 1
drill_fields:
- detail*
filters:
- action_1_time: NOT NULL
- action_2_time: NOT NULL
- event1_before_event2: True
sql: ${session_id}
- measure: count_sessions_event123
type: count_distinct
label: Action 3
description: Only includes sessions which also completed actions 1 and 2
drill_fields:
- detail*
filters:
- action_1_time: NOT NULL
- action_2_time: NOT NULL
- action_3_time: NOT NULL
- event1_before_event2: True
- event2_before_event3: True
sql: ${session_id}
- measure: count_sessions_event1234
type: count_distinct
label: Action 4
description: Only includes sessions which also completed actions 1, 2 and 3
drill_fields:
- detail*
filters:
- action_1_time: NOT NULL
- action_2_time: NOT NULL
- action_3_time: NOT NULL
- action_4_time: NOT NULL
- event1_before_event2: True
- event2_before_event3: True
- event3_before_event4: True
sql: ${session_id}
Contents
- funnel_explorer.sql
- funnel_explorer.sql
- funnel_explorer.view.lkml
- funnel_explorer.view.lookml