SQL
Mobile ticketing
Users Summary
Users Summary model for mobile ticketing.
source-preserved
Blocks
users_summary.sql · 51 lines
inferred
-- models/users_summary.sql
{{ config(materialized='view') }}
SELECT uid as user_id
, MAX(created_at) as created_at
, MAX(dob) as dob
, MAX(gender) as gender
, MAX(push_id) as push_id
, MAX(phone) as phone
, MAX(marketing_opt_in) as allow_marketing
, MAX(is_facebook) as is_facebook
, MAX(TIMESTAMP 'epoch' + ts * INTERVAL '1 Second ') as last_seen
, COUNT(case when action = 'purchase' then perm_name else null end) as purchases
, COUNT(case when action = 'waitinglist' then perm_name else null end) as reservations
, COUNT(DISTINCT(case when action = 'purchase' then perm_name else null end)) as purchased_events
, COUNT(DISTINCT(case when action = 'waitinglist' then perm_name else null end)) as reserved_events
, SUM(case when action = 'purchase' then paid else 0 end) as spendings
FROM ts_user_base
WHERE regexp_substr(uid, '@[^.]*') != ''
GROUP BY uid
# models/schema.yml
version: 2
models:
- name: users_summary
columns:
- name: user_id
tests:
- unique
- not_null
- name: created_at
- name: dob_tmp
- name: dob
- name: age
- name: age_tiers
- name: gender
- name: phone
- name: push_id
- name: allow_marketing
- name: is_facebook
- name: last_seen
- name: purchases
- name: reservations
- name: purchased_events
- name: reserved_events
- name: lifetime_purchases_tiered
- name: lifetime_reservations_tiered
- name: lifetime_purchased_events_tiered
- name: lifetime_reserved_events_tiered
- name: spendings
Assumptions
- 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.
users_summary.sql · 17 lines
source-preserved
validation: parses
SELECT uid as user_id
, MAX(created_at) as created_at
, MAX(dob) as dob
, MAX(gender) as gender
, MAX(push_id) as push_id
, MAX(phone) as phone
, MAX(marketing_opt_in) as allow_marketing
, MAX(is_facebook) as is_facebook
, MAX(TIMESTAMP 'epoch' + ts * INTERVAL '1 Second ') as last_seen
, COUNT(case when action = 'purchase' then perm_name else null end) as purchases
, COUNT(case when action = 'waitinglist' then perm_name else null end) as reservations
, COUNT(DISTINCT(case when action = 'purchase' then perm_name else null end)) as purchased_events
, COUNT(DISTINCT(case when action = 'waitinglist' then perm_name else null end)) as reserved_events
, SUM(case when action = 'purchase' then paid else 0 end) as spendings
FROM ts_user_base
WHERE regexp_substr(uid, '@[^.]*') != ''
GROUP BY uid
users_summary.view.lkml · 164 lines
inferred
view: users_summary {
derived_table: {
sql: SELECT uid as user_id
, MAX(created_at) as created_at
, MAX(dob) as dob
, MAX(gender) as gender
, MAX(push_id) as push_id
, MAX(phone) as phone
, MAX(marketing_opt_in) as allow_marketing
, MAX(is_facebook) as is_facebook
, MAX(TIMESTAMP 'epoch' + ts * INTERVAL '1 Second ') as last_seen
, COUNT(case when action = 'purchase' then perm_name else null end) as purchases
, COUNT(case when action = 'waitinglist' then perm_name else null end) as reservations
, COUNT(DISTINCT(case when action = 'purchase' then perm_name else null end)) as purchased_events
, COUNT(DISTINCT(case when action = 'waitinglist' then perm_name else null end)) as reserved_events
, SUM(case when action = 'purchase' then paid else 0 end) as spendings
FROM ts_user_base
WHERE regexp_substr(uid, '@[^.]*') != ''
GROUP BY uid ;;
}
dimension: user_id {
primary_key: yes
sql: ${TABLE}.user_id ;;
}
dimension: created_at {
type: time
sql: ${TABLE}.created_at ;;
}
dimension: dob_tmp {
type: string
hidden: yes
sql: case when (${TABLE}.dob != 'Thu 23 Jan' AND ${TABLE}.dob != 'Sat 20 Jan')
then ${TABLE}.dob
else '0001/01/01' end ;;
}
dimension: dob {
type: date
sql: to_date(${dob_tmp}, 'DD/MM/YYYY') ;;
}
dimension: age {
type: number
sql: floor(datediff(days, ${dob}, current_date)/365) ;;
}
dimension: age_tiers {
type: tier
sql: ${age} ;;
}
dimension: gender {
type: string
sql: ${TABLE}.gender ;;
}
dimension: phone {
type: string
sql: ${TABLE}.phone ;;
}
dimension: push_id {
type: string
sql: ${TABLE}.push_id ;;
}
dimension: allow_marketing {
type: yesno
sql: case when ${TABLE}.allow_marketing = 'True' then TRUE else FALSE end ;;
}
dimension: is_facebook {
type: yesno
sql: case when ${TABLE}.is_facebook = 'True' then TRUE else FALSE end ;;
}
dimension: last_seen {
type: time
sql: ${TABLE}.last_seen ;;
}
dimension: purchases {
label: "Tickets Purchased"
type: number
sql: ${TABLE}.purchases ;;
}
dimension: reservations {
label: "Wait List Tickets"
type: number
sql: ${TABLE}.reservations ;;
}
dimension: purchased_events {
type: number
sql: ${TABLE}.purchased_events ;;
}
dimension: reserved_events {
type: number
sql: ${TABLE}.reserved_events ;;
}
dimension: lifetime_purchases_tiered {
type: tier
sql: ${purchases} ;;
}
dimension: lifetime_reservations_tiered {
type: tier
sql: ${reservations} ;;
}
dimension: lifetime_purchased_events_tiered {
type: tier
sql: ${purchased_events} ;;
}
dimension: lifetime_reserved_events_tiered {
type: tier
sql: ${reserved_events} ;;
}
dimension: spendings {
label: "£ Spent"
type: number
value_format: "\"£\"#,##0"
sql: ${TABLE}.spendings / 100.0 ;;
}
measure: count_users {
type: count_distinct
drill_fields: [user_aggregation_drill_down_overview*]
sql: ${TABLE}.user_id ;;
}
measure: count_purchases {
label: "Count Tickets Purchased"
type: count_distinct
drill_fields: [user_aggregation_drill_down_overview*]
sql: ${TABLE}.purchases ;;
}
measure: count_waitlist {
label: "Count Waitlist Reserved"
type: count_distinct
sql: ${TABLE}.reservations ;;
}
measure: total_tickets_purchased {
label: "Total Tickets Purchased"
type: count_distinct
sql: ${TABLE}.purchases ;;
}
measure: total_events_reserved {
label: "Total Events Wait List"
type: count_distinct
sql: ${TABLE}.reserved_events ;;
}
}
users_summary.view.lookml · 113 lines
source-preserved
- view: users_summary
derived_table:
sql: SELECT uid as user_id
, MAX(created_at) as created_at
, MAX(dob) as dob
, MAX(gender) as gender
, MAX(push_id) as push_id
, MAX(phone) as phone
, MAX(marketing_opt_in) as allow_marketing
, MAX(is_facebook) as is_facebook
, MAX(TIMESTAMP 'epoch' + ts * INTERVAL '1 Second ') as last_seen
, COUNT(case when action = 'purchase' then perm_name else null end) as purchases
, COUNT(case when action = 'waitinglist' then perm_name else null end) as reservations
, COUNT(DISTINCT(case when action = 'purchase' then perm_name else null end)) as purchased_events
, COUNT(DISTINCT(case when action = 'waitinglist' then perm_name else null end)) as reserved_events
, SUM(case when action = 'purchase' then paid else 0 end) as spendings
FROM ts_user_base
WHERE regexp_substr(uid, '@[^.]*') != ''
GROUP BY uid
fields:
- dimension: user_id
primary_key: true
sql: ${TABLE}.user_id
- dimension: created_at
type: time
sql: ${TABLE}.created_at
- dimension: dob_tmp
type: string
hidden: true
sql: case when (${TABLE}.dob != 'Thu 23 Jan' AND ${TABLE}.dob != 'Sat 20 Jan')
then ${TABLE}.dob
else '0001/01/01' end
- dimension: dob
type: date
sql: to_date(${dob_tmp}, 'DD/MM/YYYY')
- dimension: age
type: number
sql: floor(datediff(days, ${dob}, current_date)/365)
- dimension: age_tiers
type: tier
sql: ${age}
- dimension: gender
type: string
sql: ${TABLE}.gender
- dimension: phone
type: string
sql: ${TABLE}.phone
- dimension: push_id
type: string
sql: ${TABLE}.push_id
- dimension: allow_marketing
type: yesno
sql: case when ${TABLE}.allow_marketing = 'True' then TRUE else FALSE end
- dimension: is_facebook
type: yesno
sql: case when ${TABLE}.is_facebook = 'True' then TRUE else FALSE end
- dimension: last_seen
type: time
sql: ${TABLE}.last_seen
- dimension: purchases
type: number
label: Tickets Purchased
sql: ${TABLE}.purchases
- dimension: reservations
type: number
label: Wait List Tickets
sql: ${TABLE}.reservations
- dimension: purchased_events
type: number
sql: ${TABLE}.purchased_events
- dimension: reserved_events
type: number
sql: ${TABLE}.reserved_events
- dimension: lifetime_purchases_tiered
type: tier
sql: ${purchases}
- dimension: lifetime_reservations_tiered
type: tier
sql: ${reservations}
- dimension: lifetime_purchased_events_tiered
type: tier
sql: ${purchased_events}
- dimension: lifetime_reserved_events_tiered
type: tier
sql: ${reserved_events}
- dimension: spendings
type: number
label: £ Spent
value_format: '"£"#,##0'
sql: ${TABLE}.spendings / 100.0
- measure: count_users
type: count_distinct
drill_fields:
- user_aggregation_drill_down_overview*
sql: ${TABLE}.user_id
- measure: count_purchases
type: count_distinct
label: Count Tickets Purchased
drill_fields:
- user_aggregation_drill_down_overview*
sql: ${TABLE}.purchases
- measure: count_waitlist
type: count_distinct
label: Count Waitlist Reserved
sql: ${TABLE}.reservations
- measure: total_tickets_purchased
type: count_distinct
label: Total Tickets Purchased
sql: ${TABLE}.purchases
- measure: total_events_reserved
type: count_distinct
label: Total Events Wait List
sql: ${TABLE}.reserved_events
Contents
- users_summary.sql
- users_summary.sql
- users_summary.view.lkml
- users_summary.view.lookml