diff --git a/explores/sessions.explore.lkml b/explores/sessions.explore.lkml index 2043801..4d27d09 100644 --- a/explores/sessions.explore.lkml +++ b/explores/sessions.explore.lkml @@ -5,6 +5,10 @@ include: "/attributes/*.lkml" explore: sessions { label: "GA4 Sessions" description: "Explores Google Analytics sessions data." + always_filter: { + filters: [sessions.session_date: "7 days"] + } + join: audience_cohorts { type: left_outer @@ -37,6 +41,17 @@ explore: sessions { relationship: many_to_one } + join: kraken_user_facts { + relationship: many_to_one + view_label: "Kraken User Facts" + sql_on: ${kraken_user_facts.sl_key} = ${sessions.sl_key};; + } + + join: experiment_buckets { + relationship: many_to_one + sql_on: ${experiment_buckets.sl_key} = ${sessions.sl_key} ;; + } + # join: future_purchase_prediction { # view_label: "BQML" # relationship: one_to_one diff --git a/manifest.lkml b/manifest.lkml index 87bb7f2..f0f0d7c 100644 --- a/manifest.lkml +++ b/manifest.lkml @@ -1,12 +1,12 @@ ## Connection Constants: constant: GA4_CONNECTION { - value: "looker-demos" + value: "data_warehouse_bq" export: override_required } constant: GA4_SCHEMA { - value: "adh-demo-data-review.analytics_213025502" + value: "hardy-force-319814.analytics_250111504" export: override_optional } diff --git a/views/event_data_dimensions/event_data_event_params.view.lkml b/views/event_data_dimensions/event_data_event_params.view.lkml index 47e187a..b40a45c 100644 --- a/views/event_data_dimensions/event_data_event_params.view.lkml +++ b/views/event_data_dimensions/event_data_event_params.view.lkml @@ -175,4 +175,412 @@ view: event_data_event_params { full_suggestions: yes } + ########## CUSTOM PARAMS + + dimension: custom_add_one_more_hour_action { + group_label: "Event: Additional Parameters" + label: "add_one_more_hour_action" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'add_one_more_hour_action') ;; + } + +dimension: custom_add_one_more_hour_amount { + group_label: "Event: Additional Parameters" + label: "add_one_more_hour_amount" + type: string + sql: (SELECT value.double_value FROM UNNEST(event_params) WHERE key = 'add_one_more_hour_amount') ;; + } + +dimension: custom_book_again_type { + group_label: "Event: Additional Parameters" + label: "book_again_type" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'book_again_type') ;; + } + +dimension: custom_coupon { + group_label: "Event: Additional Parameters" + label: "coupon" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'coupon') ;; + } + +dimension: custom_error_message_category { + group_label: "Event: Additional Parameters" + label: "error_message_category" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'error_message_category') ;; + } + +dimension: custom_error_message_label { + group_label: "Event: Additional Parameters" + label: "error_message_label" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'error_message_label') ;; + } + +dimension: custom_ignore_referrer { + group_label: "Event: Additional Parameters" + label: "ignore_referrer" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'ignore_referrer') ;; + } + +dimension: custom_item_list_id { + group_label: "Event: Additional Parameters" + label: "item_list_id" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'item_list_id') ;; + } + +dimension: custom_item_list_name { + group_label: "Event: Additional Parameters" + label: "item_list_name" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'item_list_name') ;; + } + +dimension: custom_om_campaign_name { + group_label: "Event: Additional Parameters" + label: "om_campaign_name" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'om_campaign_name') ;; + } + +dimension: custom_payment_type { + group_label: "Event: Additional Parameters" + label: "payment_type" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'payment_type') ;; + } + +dimension: custom_promotion_amount { + group_label: "Event: Additional Parameters" + label: "promotion_amount" + type: string + sql: (SELECT value.double_value FROM UNNEST(event_params) WHERE key = 'promotion_amount') ;; + } + +dimension: custom_promotion_name { + group_label: "Event: Additional Parameters" + label: "promotion_name" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'promotion_name') ;; + } + +dimension: custom_promotion_type { + group_label: "Event: Additional Parameters" + label: "promotion_type" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'promotion_type') ;; + } + +dimension: custom_purchased_day { + group_label: "Event: Additional Parameters" + label: "purchased_day" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'purchased_day') ;; + } + +dimension: custom_purchased_duration { + group_label: "Event: Additional Parameters" + label: "purchased_duration" + type: number + sql: (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'purchased_duration') ;; + } + +dimension: custom_purchased_product { + group_label: "Event: Additional Parameters" + label: "purchased_product" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'purchased_product') ;; + } + +dimension: custom_purchased_site { + group_label: "Event: Additional Parameters" + label: "purchased_site" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'purchased_site') ;; + } + +dimension: custom_purchased_subtype { + group_label: "Event: Additional Parameters" + label: "purchased_subtype" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'purchased_subtype') ;; + } + +dimension: custom_raf_share_location_method { + group_label: "Event: Additional Parameters" + label: "raf_share_location_method" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'raf_share_location_method') ;; + } + +dimension: custom_referral_show_or_hide { + group_label: "Event: Additional Parameters" + label: "referral_show_or_hide" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'referral_show_or_hide') ;; + } + +dimension: custom_search_count_for_sessions { + group_label: "Event: Additional Parameters" + label: "search_count_for_sessions" + type: number + sql: (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'search_count_for_sessions') ;; + } + +dimension: custom_search_results_count { + group_label: "Event: Additional Parameters" + label: "search_results_count" + type: number + sql: (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'search_results_count') ;; + } + +dimension: custom_search_results_returned { + group_label: "Event: Additional Parameters" + label: "search_results_returned" + type: number + sql: (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'search_results_returned') ;; + } + +dimension: custom_search_term { + group_label: "Event: Additional Parameters" + label: "search_term" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'search_term') ;; + } + +dimension: custom_searched_for_day { + group_label: "Event: Additional Parameters" + label: "searched_for_day" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'searched_for_day') ;; + } + +dimension: custom_searched_for_day_of_week { + group_label: "Event: Additional Parameters" + label: "searched_for_day_of_week" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'searched_for_day_of_week') ;; + } + +dimension: custom_searched_for_duration { + group_label: "Event: Additional Parameters" + label: "searched_for_duration" + type: number + sql: (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'searched_for_duration') ;; + } + +dimension: custom_searched_for_site { + group_label: "Event: Additional Parameters" + label: "searched_for_site" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'searched_for_site') ;; + } + +dimension: custom_searched_for_subtype { + group_label: "Event: Additional Parameters" + label: "searched_for_subtype" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'searched_for_subtype') ;; + } + +dimension: custom_searched_for_time { + group_label: "Event: Additional Parameters" + label: "searched_for_time" + type: number + sql: (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'searched_for_time') ;; + } + +dimension: custom_searched_for_type { + group_label: "Event: Additional Parameters" + label: "searched_for_type" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'searched_for_type') ;; + } + +dimension: custom_selected_room_availability { + group_label: "Event: Additional Parameters" + label: "selected_room_availability" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'selected_room_availability') ;; + } + +dimension: custom_transaction_id { + group_label: "Event: Additional Parameters" + label: "transaction_id" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'transaction_id') ;; + } + +dimension: custom_value { + group_label: "Event: Additional Parameters" + label: "value" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'value') ;; + } + +dimension: custom_verification_screen { + group_label: "Event: Additional Parameters" + label: "verification_screen" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'verification_screen') ;; + } +## + dimension: custom_alternative_slot_time_count { + group_label: "Event: Additional Parameters" + label: "alternative_slot_time_count" + type: number + sql: (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'alternative_slot_time_count') ;; + } + + dimension: custom_alternative_slot_time_variance { + group_label: "Event: Additional Parameters" + label: "alternative_slot_time_variance" + type: number + sql: (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'alternative_slot_time_variance') ;; + } + + dimension: custom_next_available_slots_count { + group_label: "Event: Additional Parameters" + label: "next_available_slots_count" + type: number + sql: (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'next_available_slots_count') ;; + } + + dimension: custom_previous_available_slots_count { + group_label: "Event: Additional Parameters" + label: "previous_available_slots_count" + type: number + sql: (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'previous_available_slots_count') ;; + } + + dimension: custom_same_available_slots_count { + group_label: "Event: Additional Parameters" + label: "same_available_slots_count" + type: number + sql: (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'same_available_slots_count') ;; + } + + dimension: custom_day_viewed { + group_label: "Event: Additional Parameters" + label: "day_viewed" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'day_viewed') ;; + } + + dimension: custom_braze_banner_campaign { + group_label: "Event: Additional Parameters" + label: "braze_banner_campaign" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'braze_banner_campaign') ;; + } + + dimension: ab_test_bucket { + group_label: "Event: Additional Parameters" + label: "ab_test_bucket" + type: string + sql: (SELECT value.string_value FROM UNNEST(user_properties) WHERE key = 'ab_test_bucket') ;; + } + + dimension: experiment_1_bucket { + group_label: "Event: Additional Parameters" + label: "experiment_1_bucket" + type: number + sql: (SELECT value.int_value FROM UNNEST(user_properties) WHERE key = 'experiment_1_bucket') ;; + } + + dimension: user_id_external { + group_label: "Event: Additional Parameters" + label: "user_id_external" + type: number + sql: (SELECT value.int_value FROM UNNEST(user_properties) WHERE key = 'user_id_external') ;; + } + + dimension: experiment_2_bucket { + group_label: "Event: Additional Parameters" + label: "experiment_2_bucket" + type: number + sql: (SELECT value.int_value FROM UNNEST(user_properties) WHERE key = 'experiment_2_bucket') ;; + } + + dimension: experiment_3_bucket { + group_label: "Event: Additional Parameters" + label: "experiment_3_bucket" + type: number + sql: (SELECT value.int_value FROM UNNEST(user_properties) WHERE key = 'experiment_3_bucket') ;; + } + + dimension: custom_available_points { + group_label: "Event: Additional Parameters" + label: "available_points" + type: number + sql: (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'available_points') ;; + } + + dimension: custom_redeemable_items_count { + group_label: "Event: Additional Parameters" + label: "redeemable_items_count" + type: number + sql: (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'redeemable_items_count') ;; + } + + dimension: custom_reward_type { + group_label: "Event: Additional Parameters" + label: "reward_type" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'reward_type') ;; + } + + dimension: custom_points_worth { + group_label: "Event: Additional Parameters" + label: "points_worth" + type: number + sql: (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'points_worth') ;; + } + + dimension: user { + group_label: "Event: IOS Additional Parameters" + label: "user_id" + type: number + sql: CAST((SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'user') as INT64) ;; + } + + dimension: booking { + group_label: "Event: IOS Additional Parameters" + label: "booking_id" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'booking') ;; + } + + dimension: record_mode { + group_label: "Event: IOS Additional Parameters" + label: "record_mode" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'record_mode') ;; + } + + dimension: screen_orientation { + group_label: "Event: IOS Additional Parameters" + label: "screen_orientation" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'screen_orientation') ;; + } + + dimension: camera_mode { + group_label: "Event: IOS Additional Parameters" + label: "camera_mode" + type: string + sql: (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'camera_mode') ;; + } + + dimension: recording_length { + group_label: "Event: IOS Additional Parameters" + label: "recording_length" + type: number + sql: (SELECT value.double_value FROM UNNEST(event_params) WHERE key = 'recording_length') ;; + } + } diff --git a/views/events.view.lkml b/views/events.view.lkml index 04eb308..ae44fb3 100644 --- a/views/events.view.lkml +++ b/views/events.view.lkml @@ -36,6 +36,13 @@ view: events { full_suggestions: yes } + dimension: user_id { + label: "Kraken User ID" + type: string + sql: ${TABLE}.user_id ;; + description: "The Kraken User ID associated with the event" + } + dimension: reverse_event_rank { label: "Reverse Event Rank" type: number @@ -488,10 +495,17 @@ view: events { ## User Fields dimension: user_first_touch_timestamp { + label: "User First Touch Timestamp UNIX" type: number sql: ${TABLE}.user_first_touch_timestamp ;; } + dimension: user_first_touch_timestamp_ts { + label: "User First Touch Timestamp" + type: date_time + sql: TIMESTAMP_MICROS(${TABLE}.user_first_touch_timestamp) ;; + } + dimension: user_ltv__currency { type: string sql: ${TABLE}.user_ltv.currency ;; diff --git a/views/experiment_buckets.view.lkml b/views/experiment_buckets.view.lkml new file mode 100644 index 0000000..d7f58a6 --- /dev/null +++ b/views/experiment_buckets.view.lkml @@ -0,0 +1,32 @@ +view: experiment_buckets { + + sql_table_name: pirate_dbt_prod.experiment_buckets ;; + + dimension: sl_key { + hidden: yes + primary_key: yes + sql: ${TABLE}.sl_key ;; + } + + dimension: experiment_1_bucket { + type: number + view_label: "Sessions" + group_label: "Experiment Buckets" + sql: ${TABLE}.experiment_1_bucket ;; + } + + dimension: experiment_2_bucket { + type: number + view_label: "Sessions" + group_label: "Experiment Buckets" + sql: ${TABLE}.experiment_2_bucket ;; + } + + dimension: experiment_3_bucket { + type: number + view_label: "Sessions" + group_label: "Experiment Buckets" + sql: ${TABLE}.experiment_3_bucket ;; + } + +} diff --git a/views/kraken_user_facts.view.lkml b/views/kraken_user_facts.view.lkml new file mode 100644 index 0000000..13d5adb --- /dev/null +++ b/views/kraken_user_facts.view.lkml @@ -0,0 +1,66 @@ +view: kraken_user_facts { + +derived_table: { + sql: + SELECT + ga.sl_key, + ga.user_id, + true as is_single_user_session, + u.count_bookings_paid, + u.first_booking_paid_product, + u.first_booking_paid_location, + u.revenue_percentile, + u.total_revenue + FROM pirate_dbt_prod.ga_user_id ga + LEFT JOIN pirate_dbt_prod.user_facts u on u.user_id = ga.user_id + ;; +} + +dimension: sl_key { + hidden: yes + primary_key: yes + sql: ${TABLE}.sl_key ;; +} + +dimension: session_user_id { + type: number + sql: ${TABLE}.user_id ;; +} + +dimension: is_single_user_session { + type: yesno + sql: ${TABLE}.is_single_user_session ;; + description: "did the GA session have only one kraken user? (if no they will not have kraken data)" +} + +dimension: count_bookings_paid { + type: number + sql: ${TABLE}.count_bookings_paid ;; + description: "the total number of bookings paid the user has made" +} + +dimension: first_booking_paid_product { + type: string + sql: ${TABLE}.first_booking_paid_product ;; + description: "the product associated with the user's first booking paid" +} + +dimension: first_booking_paid_location { + type: string + sql: ${TABLE}.first_booking_paid_location ;; + description: "the location associated with the user's first booking paid" +} + +dimension: revenue_percentile { + type: number + sql: ${TABLE}.revenue_percentile ;; + description: "the percentile into which the user falls based on total booking revenue" +} + +dimension: total_revenue { + type: number + sql: ${TABLE}.total_revenue ;; + description: "the total revenue associated with the user" +} + +} diff --git a/views/sessions.view.lkml b/views/sessions.view.lkml index 55ce2d6..da50287 100644 --- a/views/sessions.view.lkml +++ b/views/sessions.view.lkml @@ -2,214 +2,29 @@ include: "/views/event_data_dimensions/event_funnel.view" include: "/views/event_data_dimensions/page_funnel.view" view: sessions { - derived_table: { - datagroup_trigger: ga4_default_datagroup - partition_keys: ["session_date"] - cluster_keys: ["session_date"] - increment_key: "session_date" - increment_offset: 3 - sql: with --- obtains a list of sessions, uniquely identified by the table date, ga_session_id event parameter, ga_session_number event parameter, and the user_pseudo_id. -session_list_with_event_history as ( - select timestamp(PARSE_DATE('%Y%m%d', REGEXP_EXTRACT(_TABLE_SUFFIX,r'[0-9]+'))) session_date - , (select value.int_value from UNNEST(events.event_params) where key = "ga_session_id") ga_session_id - , (select value.int_value from UNNEST(events.event_params) where key = "ga_session_number") ga_session_number - , events.user_pseudo_id - -- unique key for session: - , timestamp(PARSE_DATE('%Y%m%d', REGEXP_EXTRACT(_TABLE_SUFFIX,r'[0-9]+')))||(select value.int_value from UNNEST(events.event_params) where key = "ga_session_id")||(select value.int_value from UNNEST(events.event_params) where key = "ga_session_number")||events.user_pseudo_id sl_key - , row_number() over (partition by (timestamp(PARSE_DATE('%Y%m%d', REGEXP_EXTRACT(_TABLE_SUFFIX,r'[0-9]+')))||(select value.int_value from UNNEST(events.event_params) where key = "ga_session_id")||(select value.int_value from UNNEST(events.event_params) where key = "ga_session_number")||events.user_pseudo_id) order by events.event_timestamp) event_rank - , (TIMESTAMP_DIFF(TIMESTAMP_MICROS(LEAD(events.event_timestamp) OVER (PARTITION BY timestamp(PARSE_DATE('%Y%m%d', REGEXP_EXTRACT(_TABLE_SUFFIX,r'[0-9]+')))||(select value.int_value from UNNEST(events.event_params) where key = "ga_session_id")||(select value.int_value from UNNEST(events.event_params) where key = "ga_session_number")||events.user_pseudo_id ORDER BY events.event_timestamp asc)) - ,TIMESTAMP_MICROS(events.event_timestamp),second)/86400.0) time_to_next_event - , case when events.event_name = 'page_view' then row_number() over (partition by (timestamp(PARSE_DATE('%Y%m%d', REGEXP_EXTRACT(_TABLE_SUFFIX,r'[0-9]+')))||(select value.int_value from UNNEST(events.event_params) where key = "ga_session_id")||(select value.int_value from UNNEST(events.event_params) where key = "ga_session_number")||events.user_pseudo_id), case when events.event_name = 'page_view' then true else false end order by events.event_timestamp) - else 0 end as page_view_rank - , case when events.event_name = 'page_view' then row_number() over (partition by (timestamp(PARSE_DATE('%Y%m%d', REGEXP_EXTRACT(_TABLE_SUFFIX,r'[0-9]+')))||(select value.int_value from UNNEST(events.event_params) where key = "ga_session_id")||(select value.int_value from UNNEST(events.event_params) where key = "ga_session_number")||events.user_pseudo_id), case when events.event_name = 'page_view' then true else false end order by events.event_timestamp desc) - else 0 end as page_view_reverse_rank - , case when events.event_name = 'page_view' then (TIMESTAMP_DIFF(TIMESTAMP_MICROS(LEAD(events.event_timestamp) OVER (PARTITION BY timestamp(PARSE_DATE('%Y%m%d', REGEXP_EXTRACT(_TABLE_SUFFIX,r'[0-9]+')))||(select value.int_value from UNNEST(events.event_params) where key = "ga_session_id")||(select value.int_value from UNNEST(events.event_params) where key = "ga_session_number")||events.user_pseudo_id , case when events.event_name = 'page_view' then true else false end ORDER BY events.event_timestamp asc)) - ,TIMESTAMP_MICROS(events.event_timestamp),second)/86400.0) else null end as time_to_next_page -- this window function yields 0 duration results when session page_view count = 1. - -- raw event data: - , events.event_date - , events.event_timestamp - , events.event_name - , events.event_params - , events.event_previous_timestamp - , events.event_value_in_usd - , events.event_bundle_sequence_id - , events.event_server_timestamp_offset - , events.user_id - -- , events.user_pseudo_id - , events.user_properties - , events.user_first_touch_timestamp - , events.user_ltv - , events.device - , events.geo - , events.app_info - , events.traffic_source - , events.stream_id - , events.platform - , events.event_dimensions - , events.ecommerce - , events.items - from `@{GA4_SCHEMA}.@{GA4_TABLE_VARIABLE}` events - where {% incrementcondition %} timestamp(PARSE_DATE('%Y%m%d', REGEXP_EXTRACT(_TABLE_SUFFIX,r'[0-9]+'))) {% endincrementcondition %} - -- where timestamp(PARSE_DATE('%Y%m%d', REGEXP_EXTRACT(_TABLE_SUFFIX,r'[0-9]+'))) >= ((TIMESTAMP_ADD(TIMESTAMP_TRUNC(CURRENT_TIMESTAMP(), DAY), INTERVAL -29 DAY))) - -- and timestamp(PARSE_DATE('%Y%m%d', REGEXP_EXTRACT(_TABLE_SUFFIX,r'[0-9]+'))) <= ((TIMESTAMP_ADD(TIMESTAMP_ADD(TIMESTAMP_TRUNC(CURRENT_TIMESTAMP(), DAY), INTERVAL -29 DAY), INTERVAL 30 DAY))) - ), - --- Session-Level Facts, session start, end, duration -session_facts as ( - select sl.sl_key - , COUNT(sl.event_timestamp) session_event_count - , SUM(case when sl.event_name = 'page_view' then 1 else 0 end) session_page_view_count - , COALESCE(SUM((select value.int_value from UNNEST(sl.event_params) where key = "engaged_session_event")),0) engaged_events - , case when (COALESCE(SUM((select value.int_value from UNNEST(sl.event_params) where key = "engaged_session_event")),0) = 0 - and COALESCE(SUM((select coalesce(cast(value.string_value as INT64),value.int_value) from UNNEST(sl.event_params) where key = "session_engaged"))) = 0) - then false else true end as is_engaged_session - , case when countif(event_name = 'first_visit') = 0 then false else true end as is_first_visit_session - , MAX(TIMESTAMP_MICROS(sl.event_timestamp)) as session_end - , MIN(TIMESTAMP_MICROS(sl.event_timestamp)) as session_start - , (MAX(sl.event_timestamp) - MIN(sl.event_timestamp))/(60 * 1000 * 1000) AS session_length_minutes - from session_list_with_event_history sl - group by 1 - ), - --- Retrieves the last non-direct medium, source, and campaign from the session's page_view events. -session_tags as ( - select distinct sl.sl_key - , first_value((select value.string_value from unnest(sl.event_params) where key = 'medium')) over (partition by sl.sl_key order by sl.event_timestamp desc) medium - , first_value((select value.string_value from unnest(sl.event_params) where key = 'source')) over (partition by sl.sl_key order by sl.event_timestamp desc) source - , first_value((select value.string_value from unnest(sl.event_params) where key = 'campaign')) over (partition by sl.sl_key order by sl.event_timestamp desc) campaign - , first_value((select value.string_value from unnest(sl.event_params) where key = 'page_referrer')) over (partition by sl.sl_key order by sl.event_timestamp desc) page_referrer - from session_list_with_event_history sl - where sl.event_name in ('page_view') - and (select value.string_value from unnest(sl.event_params) where key = 'medium') is not null -- NULL medium is direct, filtering out nulls to ensure last non-direct. - ), - --- Device and Geo Columns from 'Session Start' event. -device_geo as ( - select sl.sl_key - , sl.device.category device__category - , sl.device.mobile_brand_name device__mobile_brand_name - , sl.device.mobile_model_name device__mobile_model_name - , sl.device.mobile_brand_name||' '||device.mobile_model_name device__mobile_device_info - , sl.device.mobile_marketing_name device__mobile_marketing_name - , sl.device.mobile_os_hardware_model device__mobile_os_hardware_model - , sl.device.operating_system device__operating_system - , sl.device.operating_system_version device__operating_system_version - , sl.device.vendor_id device__vendor_id - , sl.device.advertising_id device__advertising_id - , sl.device.language device__language - , sl.device.time_zone_offset_seconds device__time_zone_offset_seconds - , sl.device.is_limited_ad_tracking device__is_limited_ad_tracking - , sl.device.web_info.browser device__web_info_browser - , sl.device.web_info.browser_version device__web_info_browser_version - , sl.device.web_info.hostname device__web_info_hostname - , case when sl.device.category = 'mobile' then true else false end as device__is_mobile - , sl.geo.continent geo__continent - , sl.geo.country geo__country - , sl.geo.city geo__city - , sl.geo.metro geo__metro - , sl.geo.sub_continent geo__sub_continent - , sl.geo.region geo__region - from session_list_with_event_history sl - where sl.event_name = 'session_start' - ), - --- Packs the event-level data into an array of structs, leaving a session-level row. -session_event_packing as ( - select sl.session_date session_date - , sl.ga_session_id ga_session_id - , sl.ga_session_number ga_session_number - , sl.user_pseudo_id user_pseudo_id - , sl.sl_key - , ARRAY_AGG(STRUCT( sl.sl_key - , sl.event_rank - , sl.page_view_rank - , sl.page_view_reverse_rank - , sl.time_to_next_event - , sl.time_to_next_page - , sl.event_date - , sl.event_timestamp - , sl.event_name - , sl.event_params - , sl.event_previous_timestamp - , sl.event_value_in_usd - , sl.event_bundle_sequence_id - , sl.event_server_timestamp_offset - , sl.user_id - , sl.user_pseudo_id - , sl.user_properties - , sl.user_first_touch_timestamp - , sl.user_ltv - , sl.device - , sl.geo - , sl.app_info - , sl.traffic_source - , sl.stream_id - , sl.platform - , sl.event_dimensions - , sl.ecommerce - , sl.items)) event_data - from session_list_with_event_history sl - group by 1,2,3,4,5 - ) - --- Final Select Statement: -select se.session_date session_date - , se.ga_session_id ga_session_id - , se.ga_session_number ga_session_number - , se.user_pseudo_id user_pseudo_id - , se.sl_key - -- packing session-level data into structs by category - , (SELECT AS STRUCT coalesce(sa.medium,'(none)') medium -- sessions missing last-non-direct are direct - , coalesce(sa.source,'(direct)') source - , coalesce(sa.campaign,'(direct)') campaign - , sa.page_referrer) session_attribution - , (SELECT AS STRUCT sf.session_event_count - , sf.engaged_events - , sf.session_page_view_count - , sf.is_engaged_session - , sf.is_first_visit_session - , sf.session_end - , sf.session_start - , sf.session_length_minutes) session_data - , (SELECT AS STRUCT d.device__category - , d.device__mobile_brand_name - , d.device__mobile_model_name - , d.device__mobile_device_info - , d.device__mobile_marketing_name - , d.device__mobile_os_hardware_model - , d.device__operating_system - , d.device__operating_system_version - , d.device__vendor_id - , d.device__advertising_id - , d.device__language - , d.device__time_zone_offset_seconds - , d.device__is_limited_ad_tracking - , d.device__web_info_browser - , d.device__web_info_browser_version - , d.device__web_info_hostname - , d.device__is_mobile) device_data - , (SELECT AS STRUCT d.geo__continent - , d.geo__country - , d.geo__city - , d.geo__metro - , d.geo__sub_continent - , d.geo__region) geo_data - , se.event_data event_data -from session_event_packing se -left join session_tags sa - on se.sl_key = sa.sl_key -left join session_facts sf - on se.sl_key = sf.sl_key -left join device_geo d - on se.sl_key = d.sl_key - ;; - } + sql_table_name: pirate_dbt_prod.ga_sessions_degranulated ;; + +#sql_table_name: pirate_dbt_prod.{% parameter ${ga_version} %} ;; extends: [event_funnel, page_funnel] ## Parameters + parameter: ga_version { + label: "GA version" + view_label: "Sessions" + type: unquoted + default_value: "ga_sessions_degranulated" + allowed_value: { + label: "Fast" + value: "ga_sessions_degranulated" + } + allowed_value: { + label: "Slow" + value: "ga_sessions" + } + } + parameter: audience_selector { view_label: "Audience" description: "Use to set 'Audience Trait' field to dynamically choose a user cohort." @@ -233,7 +48,7 @@ extends: [event_funnel, page_funnel] type: string sql: ${TABLE}.sl_key ;; primary_key: yes - hidden: yes + hidden: no } dimension_group: session { @@ -278,6 +93,13 @@ extends: [event_funnel, page_funnel] ## It is necessary for proper unnesting in the model Join. } + dimension: event_names_list { + group_label: "Session: Additional Parameters" + sql: (SELECT STRING_AGG(DISTINCT event_history.event_name) + FROM UNNEST(sessions.event_data) as event_history + WHERE event_history.sl_key = sessions.sl_key) ;; + } + dimension: audience_trait { view_label: "Audience" group_label: "Audience Cohorts" @@ -437,7 +259,7 @@ extends: [event_funnel, page_funnel] label: "Channel" description: "Default Channel Grouping as defined in https://support.google.com/analytics/answer/9756891?hl=en" ## UPDATED: 2022-07-27 - sql: + sql: case -- DIRECT when ${session_attribution_source} = '(direct)' @@ -518,7 +340,9 @@ extends: [event_funnel, page_funnel] 'tiktok.com','tinyurl','tinyurl.com','toolbox','toolbox.com','touch.facebook.com','tr.pinterest.com','travellerspoint','travellerspoint.com','tripadvisor','tripadvisor.com','trombi','trombi.com','tudou','tudou.com','tuenti','tuenti.com','tumblr','tumblr.com','tweetdeck','tweetdeck.com', 'twitter','twitter.com','twoo.com','typepad','typepad.com','unblog.fr','urbanspoon.com','ushareit.com','ushi.cn','vampirefreaks','vampirefreaks.com','vampirerave','vampirerave.com','vg.no','video.ibm.com','vk.com','vkontakte.ru','wakoopa','wakoopa.com','wattpad','wattpad.com','web.facebook.com', 'web.skype.com','webshots','webshots.com','wechat','wechat.com','weebly','weebly.com','weibo','weibo.com','wer-weiss-was.de','weread','weread.com','whatsapp','whatsapp.com','wiki.answers.com','wikihow.com','wikitravel.org','woot.com','wordpress','wordpress.com','wordpress.org','xanga', - 'xanga.com','xing','xing.com','yahoo-mbga.jp','yammer','yammer.com','yelp','yelp.co.uk','yelp.com','youroom.in','za.pinterest.com','zalo','zoo.gr','zooppa','zooppa.com' + 'xanga.com','xing','xing.com','yahoo-mbga.jp','yammer','yammer.com','yelp','yelp.co.uk','yelp.com','youroom.in','za.pinterest.com','zalo','zoo.gr','zooppa','zooppa.com', + + 'Instagram_Stories','Instagram_Feed','Facebook_Mobile_Feed','Instagram_Reels','Facebook_Desktop_Feed' ) and REGEXP_CONTAINS(${session_attribution_medium}, r"^(.*cp.*|ppc|paid.*)$") = true then 'Paid Social' @@ -585,7 +409,9 @@ extends: [event_funnel, page_funnel] 'tiktok.com','tinyurl','tinyurl.com','toolbox','toolbox.com','touch.facebook.com','tr.pinterest.com','travellerspoint','travellerspoint.com','tripadvisor','tripadvisor.com','trombi','trombi.com','tudou','tudou.com','tuenti','tuenti.com','tumblr','tumblr.com','tweetdeck','tweetdeck.com', 'twitter','twitter.com','twoo.com','typepad','typepad.com','unblog.fr','urbanspoon.com','ushareit.com','ushi.cn','vampirefreaks','vampirefreaks.com','vampirerave','vampirerave.com','vg.no','video.ibm.com','vk.com','vkontakte.ru','wakoopa','wakoopa.com','wattpad','wattpad.com','web.facebook.com', 'web.skype.com','webshots','webshots.com','wechat','wechat.com','weebly','weebly.com','weibo','weibo.com','wer-weiss-was.de','weread','weread.com','whatsapp','whatsapp.com','wiki.answers.com','wikihow.com','wikitravel.org','woot.com','wordpress','wordpress.com','wordpress.org','xanga', - 'xanga.com','xing','xing.com','yahoo-mbga.jp','yammer','yammer.com','yelp','yelp.co.uk','yelp.com','youroom.in','za.pinterest.com','zalo','zoo.gr','zooppa','zooppa.com' + 'xanga.com','xing','xing.com','yahoo-mbga.jp','yammer','yammer.com','yelp','yelp.co.uk','yelp.com','youroom.in','za.pinterest.com','zalo','zoo.gr','zooppa','zooppa.com', + + 'Instagram_Stories','Instagram_Feed','Facebook_Mobile_Feed','Instagram_Reels','Facebook_Desktop_Feed' ) or REGEXP_CONTAINS(${session_attribution_medium}, r"(social|social-network|social-media|sm|social network|social media)") = true then 'Organic Social' @@ -833,9 +659,9 @@ extends: [event_funnel, page_funnel] sql: ${geo_data}.geo__region ;; map_layer_name: us_states } - + # ## GA4 BQML fields ## - + # parameter: prediction_window_days { # view_label: "BQML" # type: number