SQL
Ecommerce marketplace
User Retention Facts
User Retention Facts model for ecommerce marketplace.
source-preserved
Blocks
user_retention_facts.sql · 40 lines
inferred
-- models/user_retention_facts.sql
{{ config(materialized='view') }}
SELECT b.profile_id as profile_id
, COUNT(DISTINCT CASE WHEN b.create_date > ftb.ftb AND b.create_date <= ftb.ftb + INTERVAL '30 DAYS' THEN b.id ELSE null END) AS booking_day_0_to_30
, COUNT(DISTINCT CASE WHEN b.create_date > ftb.ftb AND b.create_date <= ftb.ftb + INTERVAL '60 DAYS' THEN b.id ELSE null END) AS booking_day_0_to_60
, COUNT(DISTINCT CASE WHEN b.create_date > ftb.ftb AND b.create_date <= ftb.ftb + INTERVAL '90 DAYS' THEN b.id ELSE null END) AS booking_day_0_to_90
, COUNT(DISTINCT CASE WHEN b.create_date > ftb.ftb AND b.create_date <= ftb.ftb + INTERVAL '180 DAYS' THEN b.id ELSE null END) AS booking_day_0_to_180
, COUNT(DISTINCT CASE WHEN b.create_date > ftb.ftb + INTERVAL '30 DAYS' AND b.create_date <= ftb.ftb + INTERVAL '60 DAYS' THEN b.id ELSE null END) AS booking_day_30_to_60
FROM bookings_booking AS b
LEFT JOIN (
SELECT b.profile_id as profile_id
, MIN(b.create_date) as ftb
FROM bookings_booking AS b
WHERE b.status = 10
GROUP BY 1) AS ftb
ON ftb.profile_id = b.profile_id
WHERE b.status = 10
GROUP BY 1
# models/schema.yml
version: 2
models:
- name: user_retention_facts
columns:
- name: profile_id
tests:
- unique
- not_null
- name: booking_day_0_to_30
- name: has_booking_day_0_to_30
- name: booking_day_0_to_60
- name: has_booking_day_0_to_60
- name: booking_day_0_to_90
- name: has_booking_day_0_to_90
- name: booking_day_0_to_180
- name: has_booking_day_0_to_180
- name: booking_day_30_to_60
- name: has_booking_day_30_to_60
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.
user_retention_facts.sql · 16 lines
source-preserved
validation: parses
SELECT b.profile_id as profile_id
, COUNT(DISTINCT CASE WHEN b.create_date > ftb.ftb AND b.create_date <= ftb.ftb + INTERVAL '30 DAYS' THEN b.id ELSE null END) AS booking_day_0_to_30
, COUNT(DISTINCT CASE WHEN b.create_date > ftb.ftb AND b.create_date <= ftb.ftb + INTERVAL '60 DAYS' THEN b.id ELSE null END) AS booking_day_0_to_60
, COUNT(DISTINCT CASE WHEN b.create_date > ftb.ftb AND b.create_date <= ftb.ftb + INTERVAL '90 DAYS' THEN b.id ELSE null END) AS booking_day_0_to_90
, COUNT(DISTINCT CASE WHEN b.create_date > ftb.ftb AND b.create_date <= ftb.ftb + INTERVAL '180 DAYS' THEN b.id ELSE null END) AS booking_day_0_to_180
, COUNT(DISTINCT CASE WHEN b.create_date > ftb.ftb + INTERVAL '30 DAYS' AND b.create_date <= ftb.ftb + INTERVAL '60 DAYS' THEN b.id ELSE null END) AS booking_day_30_to_60
FROM bookings_booking AS b
LEFT JOIN (
SELECT b.profile_id as profile_id
, MIN(b.create_date) as ftb
FROM bookings_booking AS b
WHERE b.status = 10
GROUP BY 1) AS ftb
ON ftb.profile_id = b.profile_id
WHERE b.status = 10
GROUP BY 1
user_retention_facts.view.lkml · 124 lines
inferred
view: user_retention_facts {
derived_table: {
sql: SELECT b.profile_id as profile_id
, COUNT(DISTINCT CASE WHEN b.create_date > ftb.ftb AND b.create_date <= ftb.ftb + INTERVAL '30 DAYS' THEN b.id ELSE null END) AS booking_day_0_to_30
, COUNT(DISTINCT CASE WHEN b.create_date > ftb.ftb AND b.create_date <= ftb.ftb + INTERVAL '60 DAYS' THEN b.id ELSE null END) AS booking_day_0_to_60
, COUNT(DISTINCT CASE WHEN b.create_date > ftb.ftb AND b.create_date <= ftb.ftb + INTERVAL '90 DAYS' THEN b.id ELSE null END) AS booking_day_0_to_90
, COUNT(DISTINCT CASE WHEN b.create_date > ftb.ftb AND b.create_date <= ftb.ftb + INTERVAL '180 DAYS' THEN b.id ELSE null END) AS booking_day_0_to_180
, COUNT(DISTINCT CASE WHEN b.create_date > ftb.ftb + INTERVAL '30 DAYS' AND b.create_date <= ftb.ftb + INTERVAL '60 DAYS' THEN b.id ELSE null END) AS booking_day_30_to_60
FROM bookings_booking AS b
LEFT JOIN (
SELECT b.profile_id as profile_id
, MIN(b.create_date) as ftb
FROM bookings_booking AS b
WHERE b.status = 10
GROUP BY 1) AS ftb
ON ftb.profile_id = b.profile_id
WHERE b.status = 10
GROUP BY 1 ;;
}
dimension: profile_id {
type: int
primary_key: yes
sql: ${TABLE}.profile_id ;;
}
dimension: booking_day_0_to_30 {
type: int
sql: ${TABLE}.booking_day_0_to_30 ;;
}
dimension: has_booking_day_0_to_30 {
type: yesno
sql: ${booking_day_0_to_30} > 0 ;;
}
dimension: booking_day_0_to_60 {
type: int
sql: ${TABLE}.booking_day_0_to_60 ;;
}
dimension: has_booking_day_0_to_60 {
type: yesno
sql: ${booking_day_0_to_60} > 0 ;;
}
dimension: booking_day_0_to_90 {
type: int
sql: ${TABLE}.booking_day_0_to_90 ;;
}
dimension: has_booking_day_0_to_90 {
type: yesno
sql: ${booking_day_0_to_90} > 0 ;;
}
dimension: booking_day_0_to_180 {
type: int
sql: ${TABLE}.booking_day_0_to_180 ;;
}
dimension: has_booking_day_0_to_180 {
type: yesno
sql: ${booking_day_0_to_180} > 0 ;;
}
dimension: booking_day_30_to_60 {
type: int
sql: ${TABLE}.booking_day_30_to_60 ;;
}
dimension: has_booking_day_30_to_60 {
type: yesno
sql: ${booking_day_30_to_60} > 0 ;;
}
measure: count {
type: count
}
measure: count_booking_0_to_30 {
type: count
filters: [has_booking_day_0_to_30: "yes"]
}
measure: percent_booking_0_to_30 {
label: "Repeat Booking 1-30 Days After First Booking"
type: number
sql: 100.0 * ${count_booking_0_to_30} / NULLIF(${count},0) ;;
}
measure: count_booking_0_to_60 {
type: count
filters: [has_booking_day_0_to_60: "yes"]
}
measure: percent_booking_0_to_60 {
label: "Repeat Booking 1-60 Days After First Booking"
type: number
sql: 100.0 * ${count_booking_0_to_60} / NULLIF(${count},0) ;;
}
measure: count_booking_0_to_90 {
type: count
filters: [has_booking_day_0_to_90: "yes"]
}
measure: percent_booking_0_to_90 {
label: "Repeat Booking 1-90 Days After First Booking"
type: number
sql: 100.0 * ${count_booking_0_to_90} / NULLIF(${count},0) ;;
}
measure: count_booking_0_to_180 {
type: count
filters: [has_booking_day_0_to_180: "yes"]
}
measure: percent_booking_0_to_180 {
label: "Repeat Booking 1-180 Days After First Booking"
type: number
sql: 100.0 * ${count_booking_0_to_180} / NULLIF(${count},0) ;;
}
}
user_retention_facts.view.lookml · 87 lines
source-preserved
- view: user_retention_facts
derived_table:
sql: SELECT b.profile_id as profile_id
, COUNT(DISTINCT CASE WHEN b.create_date > ftb.ftb AND b.create_date <= ftb.ftb + INTERVAL '30 DAYS' THEN b.id ELSE null END) AS booking_day_0_to_30
, COUNT(DISTINCT CASE WHEN b.create_date > ftb.ftb AND b.create_date <= ftb.ftb + INTERVAL '60 DAYS' THEN b.id ELSE null END) AS booking_day_0_to_60
, COUNT(DISTINCT CASE WHEN b.create_date > ftb.ftb AND b.create_date <= ftb.ftb + INTERVAL '90 DAYS' THEN b.id ELSE null END) AS booking_day_0_to_90
, COUNT(DISTINCT CASE WHEN b.create_date > ftb.ftb AND b.create_date <= ftb.ftb + INTERVAL '180 DAYS' THEN b.id ELSE null END) AS booking_day_0_to_180
, COUNT(DISTINCT CASE WHEN b.create_date > ftb.ftb + INTERVAL '30 DAYS' AND b.create_date <= ftb.ftb + INTERVAL '60 DAYS' THEN b.id ELSE null END) AS booking_day_30_to_60
FROM bookings_booking AS b
LEFT JOIN (
SELECT b.profile_id as profile_id
, MIN(b.create_date) as ftb
FROM bookings_booking AS b
WHERE b.status = 10
GROUP BY 1) AS ftb
ON ftb.profile_id = b.profile_id
WHERE b.status = 10
GROUP BY 1
fields:
- dimension: profile_id
type: int
primary_key: true
sql: ${TABLE}.profile_id
- dimension: booking_day_0_to_30
type: int
sql: ${TABLE}.booking_day_0_to_30
- dimension: has_booking_day_0_to_30
type: yesno
sql: ${booking_day_0_to_30} > 0
- dimension: booking_day_0_to_60
type: int
sql: ${TABLE}.booking_day_0_to_60
- dimension: has_booking_day_0_to_60
type: yesno
sql: ${booking_day_0_to_60} > 0
- dimension: booking_day_0_to_90
type: int
sql: ${TABLE}.booking_day_0_to_90
- dimension: has_booking_day_0_to_90
type: yesno
sql: ${booking_day_0_to_90} > 0
- dimension: booking_day_0_to_180
type: int
sql: ${TABLE}.booking_day_0_to_180
- dimension: has_booking_day_0_to_180
type: yesno
sql: ${booking_day_0_to_180} > 0
- dimension: booking_day_30_to_60
type: int
sql: ${TABLE}.booking_day_30_to_60
- dimension: has_booking_day_30_to_60
type: yesno
sql: ${booking_day_30_to_60} > 0
- measure: count
type: count
- measure: count_booking_0_to_30
type: count
filters:
- has_booking_day_0_to_30: yes
- measure: percent_booking_0_to_30
type: number
label: Repeat Booking 1-30 Days After First Booking
sql: 100.0 * ${count_booking_0_to_30} / NULLIF(${count},0)
- measure: count_booking_0_to_60
type: count
filters:
- has_booking_day_0_to_60: yes
- measure: percent_booking_0_to_60
type: number
label: Repeat Booking 1-60 Days After First Booking
sql: 100.0 * ${count_booking_0_to_60} / NULLIF(${count},0)
- measure: count_booking_0_to_90
type: count
filters:
- has_booking_day_0_to_90: yes
- measure: percent_booking_0_to_90
type: number
label: Repeat Booking 1-90 Days After First Booking
sql: 100.0 * ${count_booking_0_to_90} / NULLIF(${count},0)
- measure: count_booking_0_to_180
type: count
filters:
- has_booking_day_0_to_180: yes
- measure: percent_booking_0_to_180
type: number
label: Repeat Booking 1-180 Days After First Booking
sql: 100.0 * ${count_booking_0_to_180} / NULLIF(${count},0)
Contents
- user_retention_facts.sql
- user_retention_facts.sql
- user_retention_facts.view.lkml
- user_retention_facts.view.lookml