Hi,
First of all thanks @ernesto1 for this solution, Period over Period are a basic type of analysis to track temporal metrics and GA have a very nice approach.
Following the method described here I evolved the code (Redshift) to have this PoP comparisons in several granularities (hourly, daily, weekly, hour of day, …). The code is almost the same adding a granularity parameter to filter and several modifications adding CASEs to the days_from_first_period which I renamed to comparison_date:
parameter: granularity {
default_value: "hourly"
allowed_value: {
label: "Hourly"
value: "hourly"
}
allowed_value: {
label: "Daily"
value: "daily"
}
allowed_value: {
label: "Weekly"
value: "weekly"
}
allowed_value: {
label: "Monthly"
value: "monthly"
}
allowed_value: {
label: "Yearly"
value: "yearly"
}
allowed_value: {
label: "Hour of day"
value: "hour_of_day"
}
allowed_value: {
label: "Day of the Week"
value: "day_of_week"
}
}
dimension: comparison_date {
group_label: "Arbitrary Period Comparisons"
type: date_time
sql:
CASE
WHEN {% parameter granularity %} = 'hourly'
THEN dateadd(days, -(datediff(days, {% date_start second_period_filter %}, {% date_end second_period_filter %}))+(CASE
WHEN ${days_from_start_second} >= 0
THEN ${days_from_start_second}
WHEN ${days_from_start_first} >= 0
THEN ${days_from_start_first}
END),
dateadd(hours, ${created_hour_of_day}, {% date_end second_period_filter %}::date))
WHEN {% parameter granularity %} = 'daily'
THEN CASE
WHEN ${days_from_start_second} >= 0
THEN dateadd(days , -(datediff(days, {% date_start second_period_filter %}, {% date_end second_period_filter %}))+${days_from_start_second}, {% date_end second_period_filter %})
WHEN ${days_from_start_first} >= 0
THEN dateadd(days , -(datediff(days, {% date_start second_period_filter %}, {% date_end second_period_filter %}))+${days_from_start_first}-1, {% date_end second_period_filter %})
END
WHEN {% parameter granularity %} = 'weekly'
THEN CASE
WHEN ${days_from_start_second} >= 0
THEN date_trunc('week',dateadd(days , -(datediff(days, {% date_start second_period_filter %}, {% date_end second_period_filter %}))+${days_from_start_second}, {% date_end second_period_filter %}))
WHEN ${days_from_start_first} >= 0
THEN date_trunc('week',dateadd(days , -(datediff(days, {% date_start second_period_filter %}, {% date_end second_period_filter %}))+${days_from_start_first}, {% date_end second_period_filter %}))
END
WHEN {% parameter granularity %} = 'monthly'
THEN CASE
WHEN ${days_from_start_second} >= 0
THEN date_trunc('month',dateadd(days , -(datediff(days, {% date_start second_period_filter %}, {% date_end second_period_filter %}))+${days_from_start_second}, {% date_end second_period_filter %}))
WHEN ${days_from_start_first} >= 0
THEN date_trunc('month',dateadd(days , -(datediff(days, {% date_start second_period_filter %}, {% date_end second_period_filter %}))+${days_from_start_first}, {% date_end second_period_filter %}))
END
WHEN {% parameter granularity %} = 'yearly'
THEN CASE
WHEN ${days_from_start_second} >= 0
THEN date_trunc('year',dateadd(days , -(datediff(days, {% date_start second_period_filter %}, {% date_end second_period_filter %}))+${days_from_start_second}, {% date_end second_period_filter %}))
WHEN ${days_from_start_first} >= 0
THEN date_trunc('year',dateadd(days , -(datediff(days, {% date_start second_period_filter %}, {% date_end second_period_filter %}))+${days_from_start_first}, {% date_end second_period_filter %}))
END
WHEN {% parameter granularity %} = 'hour_of_day'
THEN dateadd(hours, ${created_hour_of_day}, {% date_end second_period_filter %}::date)
WHEN {% parameter granularity %} = 'day_of_week'
THEN dateadd(day, ${created_day_of_week_index}, dateadd(days, -7,{% date_end second_period_filter %}::date))
END;;
}
I also put this PoP code on a diferent view wich can be included in any view with:
include: "/views/PoP.view.lkml"
at the top of the target view
and
extends: [pop]
under the view section.
The only requirements for this to work as an external include is the target view have a dimension_group named created.
This way the x axis show dates instead of numbers for better readability. It still can be improved ��
Full code here:
view: pop {
parameter: granularity {
default_value: "hourly"
allowed_value: {
label: "Hourly"
value: "hourly"
}
allowed_value: {
label: "Daily"
value: "daily"
}
allowed_value: {
label: "Weekly"
value: "weekly"
}
allowed_value: {
label: "Monthly"
value: "monthly"
}
allowed_value: {
label: "Yearly"
value: "yearly"
}
allowed_value: {
label: "Hour of day"
value: "hour_of_day"
}
allowed_value: {
label: "Day of the Week"
value: "day_of_week"
}
}
filter: first_period_filter {
label: "First date"
description: "This dates ALWAYS MUST be before the second date"
group_label: "Arbitrary Period Comparisons"
type: date_time
}
filter: second_period_filter {
label: "Second date"
description: "This dates ALWAYS MUST be after the first date"
group_label: "Arbitrary Period Comparisons"
type: date_time
}
dimension: period_selected {
group_label: "Arbitrary Period Comparisons"
type: string
sql:
CASE
WHEN ${created_raw} >= {% date_start first_period_filter %}
AND ${created_raw} <= {% date_end first_period_filter %}
THEN 'First Period'
WHEN ${created_raw} >= {% date_start second_period_filter %}
AND ${created_raw} <= {% date_end second_period_filter %}
THEN 'Second Period'
END ;;
}
dimension_group: created {
type: time
timeframes: [
raw,
hour,
time,
hour_of_day,
day_of_week,
day_of_week_index,
day_of_month,
date,
week,
month,
quarter,
year
]
}
dimension: days_from_start_first {
hidden: yes
type: number
sql: DATEDIFF('day', {% date_start first_period_filter %}, ${created_date}) ;;
}
dimension: days_from_start_second {
hidden: yes
type: number
sql: DATEDIFF('day', {% date_start second_period_filter %}, ${created_date}) ;;
}
dimension: comparison_date {
group_label: "Arbitrary Period Comparisons"
type: date_time
sql:
CASE
WHEN {% parameter granularity %} = 'hourly'
THEN dateadd(days, -(datediff(days, {% date_start second_period_filter %}, {% date_end second_period_filter %}))+(CASE
WHEN ${days_from_start_second} >= 0
THEN ${days_from_start_second}
WHEN ${days_from_start_first} >= 0
THEN ${days_from_start_first}
END),
dateadd(hours, ${created_hour_of_day}, {% date_end second_period_filter %}::date))
WHEN {% parameter granularity %} = 'daily'
THEN CASE
WHEN ${days_from_start_second} >= 0
THEN dateadd(days , -(datediff(days, {% date_start second_period_filter %}, {% date_end second_period_filter %}))+${days_from_start_second}, {% date_end second_period_filter %})
WHEN ${days_from_start_first} >= 0
THEN dateadd(days , -(datediff(days, {% date_start second_period_filter %}, {% date_end second_period_filter %}))+${days_from_start_first}-1, {% date_end second_period_filter %})
END
WHEN {% parameter granularity %} = 'weekly'
THEN CASE
WHEN ${days_from_start_second} >= 0
THEN date_trunc('week',dateadd(days , -(datediff(days, {% date_start second_period_filter %}, {% date_end second_period_filter %}))+${days_from_start_second}, {% date_end second_period_filter %}))
WHEN ${days_from_start_first} >= 0
THEN date_trunc('week',dateadd(days , -(datediff(days, {% date_start second_period_filter %}, {% date_end second_period_filter %}))+${days_from_start_first}, {% date_end second_period_filter %}))
END
WHEN {% parameter granularity %} = 'monthly'
THEN CASE
WHEN ${days_from_start_second} >= 0
THEN date_trunc('month',dateadd(days , -(datediff(days, {% date_start second_period_filter %}, {% date_end second_period_filter %}))+${days_from_start_second}, {% date_end second_period_filter %}))
WHEN ${days_from_start_first} >= 0
THEN date_trunc('month',dateadd(days , -(datediff(days, {% date_start second_period_filter %}, {% date_end second_period_filter %}))+${days_from_start_first}, {% date_end second_period_filter %}))
END
WHEN {% parameter granularity %} = 'yearly'
THEN CASE
WHEN ${days_from_start_second} >= 0
THEN date_trunc('year',dateadd(days , -(datediff(days, {% date_start second_period_filter %}, {% date_end second_period_filter %}))+${days_from_start_second}, {% date_end second_period_filter %}))
WHEN ${days_from_start_first} >= 0
THEN date_trunc('year',dateadd(days , -(datediff(days, {% date_start second_period_filter %}, {% date_end second_period_filter %}))+${days_from_start_first}, {% date_end second_period_filter %}))
END
WHEN {% parameter granularity %} = 'hour_of_day'
THEN dateadd(hours, ${created_hour_of_day}, {% date_end second_period_filter %}::date)
WHEN {% parameter granularity %} = 'day_of_week'
THEN dateadd(day, ${created_day_of_week_index}, dateadd(days, -7,{% date_end second_period_filter %}::date))
END;;
}
}