Looker will not be updating this content, nor guarantees that everything is up-to-date.
This post describes the period over period (pop) Method 1: Any Two Native Timeframes highlighted in the main Methods for Period Over Period (PoP) Analysis in Looker Community post.
This example uses anorder_items
table from an e-commerce dataset. The example LookML view below is the basis of this example:
All SQL in the LookMLsql
parameters in the following examples is specific to the Redshift dialect and will need to be adapted to your database dialect. This open source project provides adapted examples in BigQuery, Snowflake, and MySQL dialects.
view: order_items {
sql_table_name: public.order_items ;;
dimension: id {
primary_key: yes
hidden: yes
type: number
sql: ${TABLE}.id ;;
}
dimension_group: created {
type: time
view_label: "_PoP"
timeframes: [
raw,
time,
hour_of_day,
date,
day_of_week,
day_of_week_index,
day_of_month,
day_of_year,
week,
week_of_year,
month,
month_name,
month_num,
quarter,
year
]
sql: ${TABLE}.created_at ;;
convert_tz: no
}
measure: count {
label: "Count of order_items"
type: count
hidden: yes
}
measure: count_orders {
label: "Count of orders"
type: count_distinct
sql: ${order_id} ;;
hidden: yes
}
measure: total_sale_price {
label: "Total Sales"
view_label: "_PoP"
type: sum
sql: ${sale_price} ;;
value_format_name: usd
drill_fields: [created_date]
}
}
This is the simplest method for implementing PoP analysis in Looker. It uses two native date timeframes and a pivot. Alternatively, you can use a yesno
field or custom filter for period-to-date comparison logic.
This method is easy to model; however, if you desire any level of user interactivity, your users will need explore
permissions and the ability to navigate and assemble Explore analyses.
Using this method, users can perform analyses like the ones below.
Year-over-year (grouped by month, pivoted by year):
Month-over-month (grouped by day of month, pivoted by month):
Advantage:
yesno
LookML field on which to filter, as in the examples above) or Liquid implementation is not required.Disadvantages:
explore
permissions.timeframe
to group the measure by (e.g., day of month). See the created
dimension_group
in the LookML example below.timeframe
to pivot by (e.g., month).yesno
LookML fields with which to filter. See the mtd_only
and ytd_only
dimensions in the LookML example below. Or, you can apply period-to-date logic with a custom Explore filter.Below is an example view file with the fields referenced above:
The SQL in the sql
parameters below is for Redshift. Be sure to adapt the example to your database dialect.
### Period over Period Method 1: Use Looker's native date dimension groups
view: order_items {
sql_table_name: public.order_items ;;
dimension: id {
primary_key: yes
hidden: yes
type: number
sql: ${TABLE}.id ;;
}
dimension_group: created {
type: time
view_label: "_PoP"
timeframes: [
raw,
time,
hour_of_day,
date,
day_of_week,
day_of_week_index,
day_of_month,
day_of_year,
week,
week_of_year,
month,
month_name,
month_num,
quarter,
year
]
sql: ${TABLE}.created_at ;;
convert_tz: no
}
#(Method 1a) you may also wish to create MTD and YTD filters in LookML
dimension: wtd_only {
group_label: "To-Date Filters"
label: "WTD"
view_label: "_PoP"
type: yesno
sql: (EXTRACT(DOW FROM ${created_raw}) < EXTRACT(DOW FROM GETDATE())
OR
(EXTRACT(DOW FROM ${created_raw}) = EXTRACT(DOW FROM GETDATE()) AND
EXTRACT(HOUR FROM ${created_raw}) < EXTRACT(HOUR FROM GETDATE()))
OR
(EXTRACT(DOW FROM ${created_raw}) = EXTRACT(DOW FROM GETDATE()) AND
EXTRACT(HOUR FROM ${created_raw}) <= EXTRACT(HOUR FROM GETDATE()) AND
EXTRACT(MINUTE FROM ${created_raw}) < EXTRACT(MINUTE FROM GETDATE()))) ;;
}
dimension: mtd_only {
group_label: "To-Date Filters"
label: "MTD"
view_label: "_PoP"
type: yesno
sql: (EXTRACT(DAY FROM ${created_raw}) < EXTRACT(DAY FROM GETDATE())
OR
(EXTRACT(DAY FROM ${created_raw}) = EXTRACT(DAY FROM GETDATE()) AND
EXTRACT(HOUR FROM ${created_raw}) < EXTRACT(HOUR FROM GETDATE()))
OR
(EXTRACT(DAY FROM ${created_raw}) = EXTRACT(DAY FROM GETDATE()) AND
EXTRACT(HOUR FROM ${created_raw}) <= EXTRACT(HOUR FROM GETDATE()) AND
EXTRACT(MINUTE FROM ${created_raw}) < EXTRACT(MINUTE FROM GETDATE()))) ;;
}
dimension: ytd_only {
group_label: "To-Date Filters"
label: "YTD"
view_label: "_PoP"
type: yesno
sql: (EXTRACT(DOY FROM ${created_raw}) < EXTRACT(DOY FROM GETDATE())
OR
(EXTRACT(DOY FROM ${created_raw}) = EXTRACT(DOY FROM GETDATE()) AND
EXTRACT(HOUR FROM ${created_raw}) < EXTRACT(HOUR FROM GETDATE()))
OR
(EXTRACT(DOY FROM ${created_raw}) = EXTRACT(DOY FROM GETDATE()) AND
EXTRACT(HOUR FROM ${created_raw}) <= EXTRACT(HOUR FROM GETDATE()) AND
EXTRACT(MINUTE FROM ${created_raw}) < EXTRACT(MINUTE FROM GETDATE()))) ;;
}
measure: count {
label: "Count of order_items"
type: count
hidden: yes
}
measure: count_orders {
label: "Count of orders"
type: count_distinct
sql: ${order_id} ;;
hidden: yes
}
measure: total_sale_price {
label: "Total Sales"
view_label: "_PoP"
type: sum
sql: ${sale_price} ;;
value_format_name: usd
drill_fields: [created_date]
}
}
# ---------- EXPLORE ----------- #
explore: order_items {
label: "PoP Method 1: Use Looker's native date dimension groups"
}
See the How to do Period-over-Period Analysis Community post for another example of implementing this method using custom filters.