How customers reach our website is important (and important for every business). What is more important and interesting is what they purchase depending on how they get to our site.

I answer lots of questions like this, so I will keep it as focused as possible on each post. This question was posed to me because we recently changed our Paid Search strategy by Product Type funnel.

In our data, we luckily track the first and last attributions of many different variables of how users reach our website in our GA4 data. So I am able to see if a customer gets to our site via a specific campaign group, and if they purchase under the same campaign group or under a different product type.

All data and variables are aliased:



WITH paid_session_base AS (
  SELECT
      e.event_date                                   AS event_date,             
      e.session_key,
      e.user_pseudo_id,
      ANY_VALUE(e.device_type)                       AS device_type,          
      ANY_VALUE(e.traffic_medium)                    AS traffic_medium,       

      /* Keep both potential transaction/order ids as strings */
      MAX(TO_VARCHAR(e.order_id_primary))            AS primary_order_id_str,  
      MAX(NULLIF(TRIM(e.order_id_alt), ''))          AS alt_order_id_str,    

      /* Unified id across sources */
      COALESCE(
        MAX(NULLIF(TRIM(e.order_id_alt), '')),
        MAX(TO_VARCHAR(e.order_id_primary))
      ) AS unified_order_ref_str

  FROM ANALYTICS.WEB.EVENTS_FLAT e
  WHERE e.property_id = :p_property_id
    AND e.traffic_medium = :p_medium                -- e.g., 'paid'
    AND e.event_date > TO_DATE(:p_start_date)

    /* Toggle this block off if you want ALL sessions (orders + non-orders) */
    AND (
          :p_include_only_sessions_with_orders = 'N'
          OR NULLIF(TRIM(e.order_id_alt), '') IS NOT NULL
          OR e.order_id_primary IS NOT NULL
        )

  GROUP BY e.session_key, e.user_pseudo_id, e.event_date
),

/* Session-level attribution rollup (first/last touch, campaign ids, etc.) */
attribution_by_session AS (
  SELECT
    s.session_key,
    ANY_VALUE(s.first_channel)               AS first_channel,
    ANY_VALUE(s.last_channel)                AS last_channel,
    ANY_VALUE(s.first_campaign_code)         AS first_campaign_code,
    ANY_VALUE(s.last_campaign_code)          AS last_campaign_code,
    ANY_VALUE(s.first_external_campaign_id)  AS first_external_campaign_id,
    ANY_VALUE(s.last_external_campaign_id)   AS last_external_campaign_id
  FROM ANALYTICS.WEB.SESSION_ATTRIBUTION s
  WHERE s.session_key IS NOT NULL
  GROUP BY s.session_key
),

/* Latest campaign names by external id (handles changing names over time) */
latest_campaign AS (
  SELECT
    CAST(c.external_campaign_id AS STRING) AS external_campaign_id_str,
    c.campaign_name
  FROM MARKETING.ADS.CAMPAIGN_SNAPSHOT c
  QUALIFY ROW_NUMBER() OVER (
    PARTITION BY c.external_campaign_id
    ORDER BY c.snapshot_date DESC
  ) = 1
),

/* Order rollups from Source A (e.g., internal commerce system) */
source_a_order_stats AS (
  SELECT
      o.order_id::NUMBER               AS order_id,
      o.order_ref::STRING              AS order_ref,
      CAST(o.order_date AS DATE)       AS order_date,
      ARRAY_AGG(DISTINCT i.product_type) AS product_types,
      'SOURCE_A'                       AS order_channel
  FROM COMMERCE.CORE.ORDERS o
  JOIN COMMERCE.CORE.ORDER_ITEMS i
    ON i.order_id = o.order_id
  GROUP BY o.order_id, o.order_ref, CAST(o.order_date AS DATE)
),

/* Order rollups from Source B (e.g., downstream export / external processor) */
source_b_order_stats AS (
  SELECT
      e.order_id::NUMBER               AS order_id,
      e.order_ref::STRING              AS order_ref,
      CAST(e.order_date AS DATE)       AS order_date,
      ARRAY_CONSTRUCT('CATEGORY_A')    AS product_types,  
      'SOURCE_B'                       AS order_channel
  FROM COMMERCE.EXPORTS.ORDER_FEED e
),

/* Union both order sources */
combined_order_stats AS (
  SELECT * FROM source_a_order_stats
  UNION ALL
  SELECT * FROM source_b_order_stats
),

/* Base join of paid sessions + attribution + campaign names + orders */
base AS (
  SELECT
    b.event_date,
    b.session_key,
    b.user_pseudo_id,
    b.device_type,
    b.traffic_medium,
    b.unified_order_ref_str,

    a.first_channel,
    a.first_campaign_code,
    a.last_channel,
    a.last_campaign_code,
    a.first_external_campaign_id,
    a.last_external_campaign_id,

    lc1.campaign_name AS first_campaign_name,
    lc2.campaign_name AS last_campaign_name,
    oref.order_ref,
    oref.product_types,

   
    CASE
      WHEN COALESCE(lc1.campaign_name, a.first_campaign_code) ILIKE '%CATEGORY_B%'
      THEN 1 ELSE 0
    END AS is_first_campaign_category_b,

    CASE
      WHEN ARRAY_CONTAINS(TO_VARIANT('CATEGORY_A'), COALESCE(oref.product_types, ARRAY_CONSTRUCT()))
      THEN 1 ELSE 0
    END AS has_category_a_in_order,

    CASE
      WHEN COALESCE(lc1.campaign_name, a.first_campaign_code) ILIKE '%CATEGORY_B%'
       AND ARRAY_CONTAINS(TO_VARIANT('CATEGORY_A'), COALESCE(oref.product_types, ARRAY_CONSTRUCT()))
      THEN 1 ELSE 0
    END AS is_first_campaign_category_b_and_category_a_order

  FROM paid_session_base b
  LEFT JOIN attribution_by_session a
    ON a.session_key = b.session_key
  LEFT JOIN latest_campaign lc1
    ON TRIM(CAST(a.first_external_campaign_id AS STRING)) = lc1.external_campaign_id_str
  LEFT JOIN latest_campaign lc2
    ON TRIM(CAST(a.last_external_campaign_id  AS STRING)) = lc2.external_campaign_id_str
  LEFT JOIN combined_order_stats oref
    ON b.unified_order_ref_str = oref.order_ref
)

/* Aggregated session/user/order flags */
SELECT
  COUNT(DISTINCT session_key)                          AS total_paid_sessions,
  COUNT(DISTINCT user_pseudo_id)                       AS total_users,
  SUM(is_first_campaign_category_b)                    AS total_first_campaign_cat_b,
  SUM(has_category_a_in_order)                         AS total_orders_with_cat_a,
  SUM(is_first_campaign_category_b_and_category_a_order) AS total_first_cat_b_and_order_cat_a
FROM base;

I was able to return to management that X% of users came through a hotel paid search campaign but purchased a show.

Leave a comment

About the Podcast

Welcome to The Houseplant Podcast, your ultimate guide to houseplants! Join us as we explore the wonders and importance of plants in our lives.

Explore the episodes