dbt Saas crm life sciences

User Retention Fact

User Retention Fact model for saas crm life sciences.

inferred

Blocks

user_retention_fact.sql · 38 lines
inferred
-- models/user_retention_fact.sql
{{ config(materialized='view') }}

SELECT
  ufe.email AS email
  , du1.created_date AS day_1_activity
  , (
      SELECT COUNT(*)
      FROM {{ ref('daily_interaction') }} AS du2
      WHERE DATE_ADD(ufe.first, INTERVAL 1 day) < du2.created_date
        AND DATE_ADD(ufe.first, INTERVAL 7 day) >= du2.created_date
        AND ufe.email = du2.email
  ) AS day_2_7_active
  , (
      SELECT COUNT(*)
      FROM {{ ref('daily_interaction') }} AS du3
      WHERE DATE_ADD(ufe.first, INTERVAL 7 day) < du3.created_date
        AND DATE_ADD(ufe.first, INTERVAL 30 day) >= du3.created_date
        AND ufe.email = du3.email
  ) AS day_8_30_active
FROM {{ ref('user_first_event_fact') }} AS ufe
LEFT JOIN {{ ref('daily_interaction') }} AS du1
ON DATE_ADD(ufe.first, INTERVAL 1 day) = du1.created_date
AND ufe.email = du1.email

# models/schema.yml
version: 2

models:
  - name: user_retention_fact
    columns:
      - name: email
        tests:
          - unique
          - not_null
      - name: day_1_activity
      - name: day_2_7_active
      - name: day_8_30_active

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.
user_retention_fact.sql · 21 lines
source-preserved validation: not checked
SELECT
  ufe.email AS email
  , du1.created_date AS day_1_activity
  , (
      SELECT COUNT(*)
      FROM ${daily_interaction.SQL_TABLE_NAME} AS du2
      WHERE DATE_ADD(ufe.first, INTERVAL 1 day) < du2.created_date
        AND DATE_ADD(ufe.first, INTERVAL 7 day) >= du2.created_date
        AND ufe.email = du2.email
  ) AS day_2_7_active
  , (
      SELECT COUNT(*)
      FROM ${daily_interaction.SQL_TABLE_NAME} AS du3
      WHERE DATE_ADD(ufe.first, INTERVAL 7 day) < du3.created_date
        AND DATE_ADD(ufe.first, INTERVAL 30 day) >= du3.created_date
        AND ufe.email = du3.email
  ) AS day_8_30_active
FROM ${user_first_event_fact.SQL_TABLE_NAME} AS ufe
LEFT JOIN ${daily_interaction.SQL_TABLE_NAME} AS du1
ON DATE_ADD(ufe.first, INTERVAL 1 day) = du1.created_date
AND ufe.email = du1.email
user_retention_fact.view.lkml · 74 lines
inferred
view: user_retention_fact {
  derived_table: {
    sql: SELECT
  ufe.email AS email
  , du1.created_date AS day_1_activity
  , (
      SELECT COUNT(*)
      FROM ${daily_interaction.SQL_TABLE_NAME} AS du2
      WHERE DATE_ADD(ufe.first, INTERVAL 1 day) < du2.created_date
        AND DATE_ADD(ufe.first, INTERVAL 7 day) >= du2.created_date
        AND ufe.email = du2.email
  ) AS day_2_7_active
  , (
      SELECT COUNT(*)
      FROM ${daily_interaction.SQL_TABLE_NAME} AS du3
      WHERE DATE_ADD(ufe.first, INTERVAL 7 day) < du3.created_date
        AND DATE_ADD(ufe.first, INTERVAL 30 day) >= du3.created_date
        AND ufe.email = du3.email
  ) AS day_8_30_active
FROM ${user_first_event_fact.SQL_TABLE_NAME} AS ufe
LEFT JOIN ${daily_interaction.SQL_TABLE_NAME} AS du1
ON DATE_ADD(ufe.first, INTERVAL 1 day) = du1.created_date
AND ufe.email = du1.email ;;
  }

  dimension: email {
    primary_key: yes
  }

  dimension: day_1_activity {
    type: yesno
    sql: ${TABLE}.day_1_activity IS NOT NULL ;;
  }

  dimension: day_2_7_active {
    type: yesno
    sql: ${TABLE}.day_2_7_active > 0 ;;
  }

  dimension: day_8_30_active {
    type: yesno
    sql: ${TABLE}.day_8_30_active > 0 ;;
  }

  measure: day_1_retention_count {
    type: count
    filters: [day_1_activity: "True"]
  }

  measure: day_2_7_active_retention_count {
    type: count
    filters: [day_2_7_active: "True"]
  }

  measure: day_8_30_active_retention_count {
    type: count
    filters: [day_8_30_active: "True"]
  }

  measure: day_1_retention_percentage {
    type: number
    sql: 100.0 * ${day_1_retention_count}/NULLIF(${users.count},0) ;;
  }

  measure: day_2_7_retention_percentage {
    type: number
    sql: 100.0 * ${day_2_7_active_retention_count}/NULLIF(${users.count},0) ;;
  }

  measure: day_8_30_retention_percentage {
    type: number
    sql: 100.0 * ${day_8_30_active_retention_count}/NULLIF(${users.count},0) ;;
  }
}
user_retention_fact.view.lookml · 56 lines
source-preserved
- view: user_retention_fact
  derived_table:
    sql: SELECT
  ufe.email AS email
  , du1.created_date AS day_1_activity
  , (
      SELECT COUNT(*)
      FROM ${daily_interaction.SQL_TABLE_NAME} AS du2
      WHERE DATE_ADD(ufe.first, INTERVAL 1 day) < du2.created_date
        AND DATE_ADD(ufe.first, INTERVAL 7 day) >= du2.created_date
        AND ufe.email = du2.email
  ) AS day_2_7_active
  , (
      SELECT COUNT(*)
      FROM ${daily_interaction.SQL_TABLE_NAME} AS du3
      WHERE DATE_ADD(ufe.first, INTERVAL 7 day) < du3.created_date
        AND DATE_ADD(ufe.first, INTERVAL 30 day) >= du3.created_date
        AND ufe.email = du3.email
  ) AS day_8_30_active
FROM ${user_first_event_fact.SQL_TABLE_NAME} AS ufe
LEFT JOIN ${daily_interaction.SQL_TABLE_NAME} AS du1
ON DATE_ADD(ufe.first, INTERVAL 1 day) = du1.created_date
AND ufe.email = du1.email
  fields:
  - dimension: email
    primary_key: true
  - dimension: day_1_activity
    type: yesno
    sql: ${TABLE}.day_1_activity IS NOT NULL
  - dimension: day_2_7_active
    type: yesno
    sql: ${TABLE}.day_2_7_active > 0
  - dimension: day_8_30_active
    type: yesno
    sql: ${TABLE}.day_8_30_active > 0
  - measure: day_1_retention_count
    type: count
    filters:
    - day_1_activity: True
  - measure: day_2_7_active_retention_count
    type: count
    filters:
    - day_2_7_active: True
  - measure: day_8_30_active_retention_count
    type: count
    filters:
    - day_8_30_active: True
  - measure: day_1_retention_percentage
    type: number
    sql: 100.0 * ${day_1_retention_count}/NULLIF(${users.count},0)
  - measure: day_2_7_retention_percentage
    type: number
    sql: 100.0 * ${day_2_7_active_retention_count}/NULLIF(${users.count},0)
  - measure: day_8_30_retention_percentage
    type: number
    sql: 100.0 * ${day_8_30_active_retention_count}/NULLIF(${users.count},0)

Contents

  • user_retention_fact.sql
  • user_retention_fact.sql
  • user_retention_fact.view.lkml
  • user_retention_fact.view.lookml