Using Liquid to dynamically adjust dimension definition of a derived table.

My situation is roughly as follows: I have a base view that contains daily pre-aggregated data with several attributes and a distinct count (stored as HLL sketch):

 

 

base_view {
dimension date {}
dimension A {}
dimension B {}
dimension C {}
dimension D {}
measure count {}
}

 

 

It's a large dataset. One of my KPIs includes calculating a ratio of daily vs. monthly (rolling last 30 day) distinct counts. I achieve the calculation of monthly counts using a derived table.

 

 

view: monthly_users {
  derived_table: {
    explore_source: base_view {
    column: date { field: monthly_date.date}
    ....

  measure: monthly_count {}
}

explore: my_explore {
  from: base_view
  join: monthly_date {
    relationship: many_to_one
    from:  dim_date
    type: inner
    view_label: "Date: last 30 days"
    sql_on:
      ${base_view.date_date}
      between DATEADD(
        DAY,
        -29,
        ${monthly_date.date_date}
      ) and ${monthly_date.date_date};;
    }
  join: monthly_counts {
    type:  inner
    relationship: many_to_one
    sql_on: ${monthly_users.date} = ${base_view.date}
      ;;
  }

 

 

I use filter binding to calculate monthly counts correctly when a user filters by one of the dimensions. However, I struggle to make the model work when a user adds a dimension to an explore. I believe I have two options:

  1. Include all the dimensions in the derived table, and add those dimensions to the join condition. While this works, it means the `monthly_users` CTE has to compute distinct counts on the original grain of the table, which is computationally expensive.
  2. Create a "dynamic dimension" on the fly based on dimensions included in the query. It would then be used calculate the monthly counts in the derived table and added as a join condition . This will result in a fan-out join (because the original table is not pre-aggregated), but given that I'm working with distinct counts, it doesn't affect the results. 

I've tried an approach like this:

 

 

base_view {
dimension A {}
dimension B {}
dimension C {}

dimension hash_dim {
sql: HASH(
{% if base_view.A._is_selected %} ${TABLE}.A, {% endif %}
{% if base_view.B._is_selected %} ${TABLE}.B, {% endif %}
{% if base_view.C._is_selected %} ${TABLE}.C, {% endif %}
);;
}
}

view: monthly_users {
  derived_table: {
    explore_source: base_view {
      column: date { field: monthly_date.date}
      column: hash_dim {field: base_view.hash_dim}
   }
  }
}

 

 

However, it seems that the Liquid filters do not evaluate to true in the derived table CTE - The generated SQL code for the derived table includes an empty `HASH()` statement while the one for the base explore/view is correct. 

Is it possible to make the 2nd approach work? Or are there alternative solutions for such a problem?

 

 

1 1 53
1 REPLY 1

I feel there's a problem in your liquid code.
If condition in liquid is written like this

 {% if condition %}
value
{% elsif condition %}
value
{% else %}
value
{% endif %};;

Top Labels in this Space