<@U07FJ89LFFB> I'm using Growthbook with GA4 + Big...
# ask-ai
w
@brash-pillow-71627 I'm using Growthbook with GA4 + Bigquery. I'm not seeing the table with results. This is the rended query of one of the metrics:
Copy code
-- Engaged Users (proportion)
WITH
  __rawExperiment AS (
    SELECT
      user_pseudo_id as anonymous_id,
      TIMESTAMP_MICROS(event_timestamp) as timestamp,
      experiment_id_param.value.string_value AS experiment_id,
      variation_id_param.value.int_value AS variation_id,
      geo.country as country,
      traffic_source.source as source,
      traffic_source.medium as medium,
      device.category as device,
      device.web_info.browser as browser,
      device.operating_system as os
    FROM
      `learning-heroes-bq`.`analytics_372696867`.`events_*`,
      UNNEST (event_params) AS experiment_id_param,
      UNNEST (event_params) AS variation_id_param
    WHERE
      (
        (_TABLE_SUFFIX BETWEEN '20250909' AND '20250909')
        OR (
          _TABLE_SUFFIX BETWEEN 'intraday_20250909' AND 'intraday_20250909'
        )
      )
      AND event_name = 'experiment_viewed'
      AND experiment_id_param.key = 'experiment_id'
      AND variation_id_param.key = 'variation_id'
      AND user_pseudo_id is not null
  ),
  __experimentExposures AS (
    -- Viewed Experiment
    SELECT
      e.anonymous_id as anonymous_id,
      cast(e.variation_id as string) as variation,
      CAST(e.timestamp as DATETIME) as timestamp
    FROM
      __rawExperiment e
    WHERE
      e.experiment_id = 'test-aa-httpsprogramaslearningheroescomia-heroesbp2'
      AND e.timestamp >= '2025-09-09 16:42:49'
      AND e.timestamp <= '2025-09-09 17:18:57'
  ),
  __experimentUnits AS (
    -- One row per user
    SELECT
      e.anonymous_id AS anonymous_id,
      (
        CASE
          WHEN count(distinct e.variation) > 1 THEN '__multiple__'
          ELSE max(e.variation)
        END
      ) AS variation,
      MIN(e.timestamp) AS first_exposure_timestamp
    FROM
      __experimentExposures e
    GROUP BY
      e.anonymous_id
  ),
  __distinctUsers AS (
    SELECT
      anonymous_id,
      variation,
      first_exposure_timestamp AS timestamp,
      date_trunc(first_exposure_timestamp, DAY) AS first_exposure_date
    FROM
      __experimentUnits
  ),
  __metric as ( -- Metric (Engaged Users)
    SELECT
      anonymous_id as anonymous_id,
      1 as value,
      CAST(m.timestamp as DATETIME) as timestamp
    FROM
      (
        SELECT
          TIMESTAMP_MICROS(event_timestamp) as timestamp,
          user_id,
          user_pseudo_id as anonymous_id,
          event_name,
          geo.country,
          device.category as device_category,
          traffic_source.source,
          traffic_source.medium,
          traffic_source.name as campaign,
          REGEXP_EXTRACT(
            (
              SELECT
                value.string_value
              FROM
                UNNEST (event_params)
              WHERE
                key = 'page_location'
            ),
            r'http[s]?:\/\/?[^\/\s]+\/([^?]*)'
          ) as page_path,
          (
            SELECT
              value.string_value
            FROM
              UNNEST (event_params)
            WHERE
              key = 'session_engaged'
          ) as session_engaged,
          event_value_in_usd,
          CAST(
            (
              SELECT
                value.int_value
              FROM
                UNNEST (event_params)
              WHERE
                key = 'ga_session_id'
            ) AS string
          ) as session_id,
          (
            SELECT
              value.int_value
            FROM
              UNNEST (event_params)
            WHERE
              key = 'engagement_time_msec'
          ) / 1000 as engagement_time
        FROM
          `learning-heroes-bq`.`analytics_372696867`.`events_*`
        WHERE
          (
            (_TABLE_SUFFIX BETWEEN '20250909' AND '20250909')
            OR (
              _TABLE_SUFFIX BETWEEN 'intraday_20250909' AND 'intraday_20250909'
            )
          )
      ) m
    WHERE
      (session_engaged = '1')
      AND m.timestamp >= '2025-09-09 16:42:49'
      AND m.timestamp <= '2025-09-09 17:18:57'
  ),
  __userMetricJoin as (
    SELECT
      d.variation AS variation,
      d.anonymous_id AS anonymous_id,
      (
        CASE
          WHEN m.timestamp >= d.timestamp
          AND m.timestamp <= '2025-09-09 17:18:57' THEN m.value
          ELSE NULL
        END
      ) as value
    FROM
      __distinctUsers d
      LEFT JOIN __metric m ON (m.anonymous_id = d.anonymous_id)
  ),
  __userMetricAgg as (
    -- Add in the aggregate metric value for each user
    SELECT
      umj.variation AS variation,
      umj.anonymous_id,
      COALESCE(MAX(umj.value), 0) as value
    FROM
      __userMetricJoin umj
    GROUP BY
      umj.variation,
      umj.anonymous_id
  )
  -- One row per variation/dimension with aggregations
SELECT
  m.variation AS variation,
  COUNT(*) AS users,
  SUM(COALESCE(m.value, 0)) AS main_sum,
  SUM(POWER(COALESCE(m.value, 0), 2)) AS main_sum_squares
FROM
  __userMetricAgg m
GROUP BY
  m.variation
Give me 10 ideas to test changing this rendered query so I can get data. I will try this in Bigquery first and if it works I will change the query in Growthbook.
b
A message from kapa.ai
Certainly! Here are 10 ideas, based on common issues and troubleshooting steps from the knowledge sources, to help you debug and adjust your rendered query so you can get data in BigQuery (and then in GrowthBook): 1. Change
variation_id_param.value.int_value
to
variation_id_param.value.string_value
Many GA4 setups store
variation_id
as a string, not an int. Try:
Copy code
sql    variation_id_param.value.string_value AS variation_id
instead of
Copy code
sql    variation_id_param.value.int_value AS variation_id
This is a frequent cause of "no data" issues in GrowthBook with GA4/BigQuery integrations [Forum example](https://linen.growthbook.io/t/29091994/we-are-unable-to-get-any-result-for-our-experiments-we-ve-wr#29091994). 2. Temporarily Remove Filters on
experiment_id
and
variation_id
Comment out or remove:
Copy code
sql    AND experiment_id_param.key = 'experiment_id'    AND variation_id_param.key = 'variation_id'
If you get rows, add them back one at a time to see which filter is causing the issue [GA4 troubleshooting](https://docs.growthbook.io/kb/google-analytics/google-analytics-ga4-troubleshooting#common-issues-when-integrating-ga4-with-growthbook). 3. Check the Date Range and Table Suffixes Make sure the
_TABLE_SUFFIX
values match the available data in your BigQuery tables. Try expanding the date range or removing the intraday logic temporarily to see if data appears. 4. Verify Dataset and Table Names Double-check that the dataset and table names in your
FROM
clause match your actual BigQuery export location. Typos or mismatches here will result in no data [GA4/BQ troubleshooting](https://docs.growthbook.io/kb/google-analytics/google-big-query-bq-troubleshooting). 5. Test for Presence of
experiment_viewed
Events
Run a simple query to check if any
experiment_viewed
events exist for your date range:
Copy code
sql    SELECT * FROM `learning-heroes-bq`.`analytics_372696867`.`events_*`    WHERE event_name = 'experiment_viewed'    LIMIT 10
If this returns no rows, the event is not being tracked or not yet exported. 6. Check for Data Propagation Delays Remember, standard GA4 → BigQuery exports have a 24-hour delay. If your experiment is very recent, data may not be available yet [BQ troubleshooting](https://docs.growthbook.io/kb/google-analytics/google-big-query-bq-troubleshooting). 7. Test the Query Without the
user_pseudo_id is not null
Filter
Remove or comment out:
Copy code
sql    AND user_pseudo_id is not null
to see if this filter is excluding all your data. 8. Check for Correct Unnesting of Event Params Ensure that the
UNNEST(event_params)
logic is correct and that both
experiment_id_param
and
variation_id_param
are being unnested from the same event. Sometimes, the wrong unnesting can result in no matches. 9. Test the Metric Query Standalone Run just the metric part (the innermost SELECT) in BigQuery to see if it returns any data for your metric event (e.g.,
session_engaged = '1'
). This helps isolate whether the issue is with the experiment join or the metric itself. 10. Check for Data Type Mismatches in Joins Ensure that the types used for joining (e.g.,
anonymous_id
) are consistent between subqueries. If one is a string and another is an int, the join will fail silently. If you find that changing
variation_id_param.value.int_value
to
variation_id_param.value.string_value
returns data, update your Experiment Assignment Query in GrowthBook accordingly. This is the most common fix for this type of issue [Forum example](https://linen.growthbook.io/t/29091994/we-are-unable-to-get-any-result-for-our-experiments-we-ve-wr#29091994). If none of these steps work, double-check that your
experiment_viewed
events are being sent to GA4 and that the data has had time to propagate to BigQuery. You can also use the "Test Query" feature in GrowthBook's Data Source settings to debug further [GA4 troubleshooting](https://docs.growthbook.io/kb/google-analytics/google-analytics-ga4-troubleshooting#common-issues-when-integrating-ga4-with-growthbook).
w
@brash-pillow-71627 I'm seeing some events with experiment_viewed but with "null" variation_id is that ok? For example: Fila event_date event_timestamp event_name event_params. key event_params.value. string_value event_params.value. int_value event_params.value. float_value event_params.value. double_value event_previous_timestamp event_value_in_usd event_bundle_sequence_id event_server_timestamp_offset user_id user_pseudo_id privacy_info. analytics_storage privacy_info. ads_storage privacy_info. uses_transient_token user_properties. key user_properties.value. string_value user_properties.value. int_value user_properties.value. float_value user_properties.value. double_value user_properties.value. set_timestamp_micros user_first_touch_timestamp user_ltv. revenue user_ltv. currency device. category device. mobile_brand_name device. mobile_model_name device. mobile_marketing_name device. mobile_os_hardware_model device. operating_system device. operating_system_version device. vendor_id device. advertising_id device. language device. is_limited_ad_tracking device. time_zone_offset_seconds device. browser device. browser_version device.web_info. browser device.web_info. browser_version device.web_info. hostname geo. city geo. country geo. continent geo. region geo. sub_continent geo. metro app_info. id app_info. version app_info. install_store app_info. firebase_app_id app_info. install_source traffic_source. name traffic_source. medium traffic_source. source stream_id platform event_dimensions. hostname ecommerce. total_item_quantity ecommerce. purchase_revenue_in_usd ecommerce. purchase_revenue ecommerce. refund_value_in_usd ecommerce. refund_value ecommerce. shipping_value_in_usd ecommerce. shipping_value ecommerce. tax_value_in_usd ecommerce. tax_value ecommerce. unique_items ecommerce. transaction_id items. item_id items. item_name items. item_brand items. item_variant items. item_category items. item_category2 items. item_category3 items. item_category4 items. item_category5 items. price_in_usd items. price items. quantity items. item_revenue_in_usd items. item_revenue items. item_refund_in_usd items. item_refund items. coupon items. affiliation items. location_id items. item_list_id items. item_list_name items. item_list_index items. promotion_id items. promotion_name items. creative_name items. creative_slot items.item_params. key items.item_params.value. string_value items.item_params.value. int_value items.item_params.value. float_value items.item_params.value. double_value collected_traffic_source. manual_campaign_id collected_traffic_source. manual_campaign_name collected_traffic_source. manual_source collected_traffic_source. manual_medium collected_traffic_source. manual_term collected_traffic_source. manual_content collected_traffic_source. manual_source_platform collected_traffic_source. manual_creative_format collected_traffic_source. manual_marketing_tactic collected_traffic_source. gclid collected_traffic_source. dclid collected_traffic_source. srsltid is_active_user batch_event_index batch_page_id batch_ordering_id session_traffic_source_last_click.manual_campaign. campaign_id session_traffic_source_last_click.manual_campaign. campaign_name session_traffic_source_last_click.manual_campaign. source session_traffic_source_last_click.manual_campaign. medium session_traffic_source_last_click.manual_campaign. term session_traffic_source_last_click.manual_campaign. content session_traffic_source_last_click.manual_campaign. source_platform session_traffic_source_last_click.manual_campaign. creative_format session_traffic_source_last_click.manual_campaign. marketing_tactic session_traffic_source_last_click.google_ads_campaign. customer_id session_traffic_source_last_click.google_ads_campaign. account_name session_traffic_source_last_click.google_ads_campaign. campaign_id session_traffic_source_last_click.google_ads_campaign. campaign_name session_traffic_source_last_click.google_ads_campaign. ad_group_id session_traffic_source_last_click.google_ads_campaign. ad_group_name session_traffic_source_last_click.cross_channel_campaign. campaign_id session_traffic_source_last_click.cross_channel_campaign. campaign_name session_traffic_source_last_click.cross_channel_campaign. source session_traffic_source_last_click.cross_channel_campaign. medium session_traffic_source_last_click.cross_channel_campaign. source_platform session_traffic_source_last_click.cross_channel_campaign. default_channel_group session_traffic_source_last_click.cross_channel_campaign. primary_channel_group session_traffic_source_last_click.sa360_campaign. campaign_id session_traffic_source_last_click.sa360_campaign. campaign_name session_traffic_source_last_click.sa360_campaign. source session_traffic_source_last_click.sa360_campaign. medium session_traffic_source_last_click.sa360_campaign. ad_group_id session_traffic_source_last_click.sa360_campaign. ad_group_name session_traffic_source_last_click.sa360_campaign. creative_format session_traffic_source_last_click.sa360_campaign. engine_account_name session_traffic_source_last_click.sa360_campaign. engine_account_type session_traffic_source_last_click.sa360_campaign. manager_account_name session_traffic_source_last_click.cm360_campaign. campaign_id session_traffic_source_last_click.cm360_campaign. campaign_name session_traffic_source_last_click.cm360_campaign. source session_traffic_source_last_click.cm360_campaign. medium session_traffic_source_last_click.cm360_campaign. account_id session_traffic_source_last_click.cm360_campaign. account_name session_traffic_source_last_click.cm360_campaign. advertiser_id session_traffic_source_last_click.cm360_campaign. advertiser_name session_traffic_source_last_click.cm360_campaign. creative_id session_traffic_source_last_click.cm360_campaign. creative_format session_traffic_source_last_click.cm360_campaign. creative_name session_traffic_source_last_click.cm360_campaign. creative_type session_traffic_source_last_click.cm360_campaign. creative_type_id session_traffic_source_last_click.cm360_campaign. creative_version session_traffic_source_last_click.cm360_campaign. placement_id session_traffic_source_last_click.cm360_campaign. placement_cost_structure session_traffic_source_last_click.cm360_campaign. placement_name session_traffic_source_last_click.cm360_campaign. rendering_id session_traffic_source_last_click.cm360_campaign. site_id session_traffic_source_last_click.cm360_campaign. site_name session_traffic_source_last_click.dv360_campaign. campaign_id session_traffic_source_last_click.dv360_campaign. campaign_name session_traffic_source_last_click.dv360_campaign. source session_traffic_source_last_click.dv360_campaign. medium session_traffic_source_last_click.dv360_campaign. advertiser_id session_traffic_source_last_click.dv360_campaign. advertiser_name session_traffic_source_last_click.dv360_campaign. creative_id session_traffic_source_last_click.dv360_campaign. creative_format session_traffic_source_last_click.dv360_campaign. creative_name session_traffic_source_last_click.dv360_campaign. exchange_id session_traffic_source_last_click.dv360_campaign. exchange_name session_traffic_source_last_click.dv360_campaign. insertion_order_id session_traffic_source_last_click.dv360_campaign. insertion_order_name session_traffic_source_last_click.dv360_campaign. line_item_id session_traffic_source_last_click.dv360_campaign. line_item_name session_traffic_source_last_click.dv360_campaign. partner_id session_traffic_source_last_click.dv360_campaign. partner_name publisher. ad_revenue_in_usd publisher. ad_format publisher. ad_source_name publisher. ad_unit_id 1 20250909 1757433475711689 experiment_viewed page_location https://programas.learningheroes.com/iah/ev/reserva-de-llamada null null null null null 1577665225 null null null No No No null null null null null null null null null desktop Apple null null null Macintosh Macintosh Intel 15.6 null null es-ar No null null null Chrome 140.0.7339.81 programas.learningheroes.com Billinghurst Argentina Americas Buenos Aires Province South America (not set) null null null null null null null null 6636853897 WEB null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null 1 1757433473928 2 null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null batch_ordering_id null 2 null null engagement_time_msec null 2 null null session_engaged 0 null null null batch_page_id null 1757433473928 null null page_title IA Heroes | Reserva de Llamada | Learning Heroes null null null experiment_id test-aa-httpsprogramaslearningheroescomiahevreserva-de-llamada null null null ga_session_number null 1 null null variation_id null
b
A message from kapa.ai
Seeing
experiment_viewed
events with a
null
value for
variation_id
is not expected and usually indicates a problem in how the event is being tracked or how the data is being extracted from GA4/BigQuery. What does this mean? - GrowthBook requires both
experiment_id
and
variation_id
to be present in the event for proper experiment analysis. - If
variation_id
is
null
, GrowthBook will not be able to attribute the exposure to a specific variation, and these events will be ignored in experiment results. Common causes: 1. Tracking Callback Misconfiguration: The
trackingCallback
may not be sending the
variation_id
correctly. Double-check your implementation to ensure that both
experiment_id
and
variation_id
are being set and pushed to GA4 (or the dataLayer, if using GTM). The correct format should look like:
Copy code
js    window.dataLayer.push({      event: "experiment_viewed",      experiment_id: experiment.key,      variation_id: result.variationId,    });
[GTM troubleshooting](https://docs.growthbook.io/kb/google-analytics/google-tag-manager-gtm-troubleshooting#common-issues-when-integrating-gtm-with-growthbook) 2. Event Parameter Extraction Issue: In your BigQuery export, ensure that the query is referencing the correct type for
variation_id
. Many setups mistakenly use
int_value
when the data is actually stored as
string_value
, or vice versa. If the wrong type is used, the value will be `null`:
Copy code
sql    variation_id_param.value.string_value AS variation_id
instead of
Copy code
sql    variation_id_param.value.int_value AS variation_id
[Forum example](https://linen.growthbook.io/t/29091994/we-are-unable-to-get-any-result-for-our-experiments-we-ve-wr#29091994) 3. Missing or Incorrect DataLayer Push: If you are using GTM, make sure the
variation_id
is being pushed to the dataLayer and mapped correctly in your GTM tag configuration. If the event structure is incorrect, GTM will not forward the value to GA4, resulting in
null
in BigQuery [GTM troubleshooting](https://docs.growthbook.io/kb/google-analytics/google-tag-manager-gtm-troubleshooting#common-issues-when-integrating-gtm-with-growthbook). What should you do? - Check your tracking code and ensure
variation_id
is always set and sent. - In your BigQuery queries, try switching between
string_value
and
int_value
for
variation_id
to match your data. - If you are using GTM, verify your dataLayer push and tag mapping. Summary: No, it is not okay to have
experiment_viewed
events with a
null
variation_id
. These events will not be counted in GrowthBook experiment results. You should review your tracking implementation and your BigQuery extraction logic to ensure
variation_id
is always present and correctly typed [GA4 troubleshooting](https://docs.growthbook.io/kb/google-analytics/google-analytics-ga4-troubleshooting#common-issues-when-integrating-ga4-with-growthbook).
w
@brash-pillow-71627 give a bigquery query that I can run so we can see if 1) there is variation_id without null values and 2) if there is anything else we are querying wrong with variation_id like what you mention in 2)
b
A message from kapa.ai
Certainly! Here’s a BigQuery query you can use to check for the presence and type of
variation_id
in your GA4 events, and to help diagnose if you’re querying the correct field (
int_value
vs
string_value
). This approach is based on the troubleshooting steps and example queries from the knowledge sources:
Copy code
sql SELECT   event_date,   event_name,   experiment_id_param.value.string_value AS experiment_id_string,   experiment_id_param.value.int_value AS experiment_id_int,   variation_id_param.value.string_value AS variation_id_string,   variation_id_param.value.int_value AS variation_id_int,   COUNT(*) AS event_count FROM   `learning-heroes-bq`.`analytics_372696867`.`events_*`,   UNNEST(event_params) AS experiment_id_param,   UNNEST(event_params) AS variation_id_param WHERE   event_name = 'experiment_viewed'   AND experiment_id_param.key = 'experiment_id'   AND variation_id_param.key = 'variation_id' GROUP BY   event_date, event_name, experiment_id_string, experiment_id_int, variation_id_string, variation_id_int ORDER BY   event_date DESC, event_count DESC
How to use this query: - This will show you, for each event, both the
string_value
and
int_value
for
variation_id
and
experiment_id
. - You can see if
variation_id_string
or
variation_id_int
is populated, or if either is always
null
. - If you see that only one of these columns is populated (and the other is always
null
), you should use that type in your GrowthBook queries. - If both are
null
, your tracking is not sending the value correctly. This approach is directly recommended in GrowthBook support and forum threads for troubleshooting GA4/BigQuery integration issues with
variation_id
[Forum example](https://linen.growthbook.io/t/30129167/u07fj89lffb-i-can-see-experiment-data-in-bigquery-but-in-gro). If you find that only
variation_id_string
or only
variation_id_int
is populated, update your GrowthBook assignment query to use the correct field accordingly.
w
@brash-pillow-71627 variation_id_int is populated. How should I change this query? Changing the query so it had this line didn't worked:
Copy code
variation_id_param.value.int_value AS variation_id AS variation_id,
b
A message from kapa.ai
Sorry @wide-cartoon-5349, I am experiencing especially high traffic right now, please try again. 🧑‍💻
A message from kapa.ai
Since your data shows that
variation_id_param.value.int_value
is populated (not
string_value
), your query is already using the correct field for
variation_id
in the
__rawExperiment
CTE:
Copy code
sql variation_id_param.value.int_value AS variation_id
This matches the recommended approach in GrowthBook for GA4/BigQuery setups where
variation_id
is stored as an integer. There is no need to change this part of your query, as long as your experiment assignment query and metric queries are consistent in using the
int_value
field for
variation_id
[Forum example](https://linen.growthbook.io/t/30129167/u07fj89lffb-i-can-see-experiment-data-in-bigquery-but-in-gro). Key points: - Keep using
variation_id_param.value.int_value AS variation_id
since your data is stored as an integer. - Do not switch to
string_value
unless your data changes to store
variation_id
as a string. - Ensure that all related queries (assignment and metrics) use the same type for
variation_id
to avoid mismatches. If you continue to see issues, double-check that all experiment events have a non-null
variation_id
and that your GrowthBook assignment query matches this structure. If you ever change your tracking to use string values, you would need to update this field accordingly, but for now, your current approach is correct based on your data and the knowledge sources.
A message from kapa.ai
You should remove the duplicate alias in your query. The correct syntax is:
Copy code
sql variation_id_param.value.int_value AS variation_id,
Do not use:
Copy code
sql variation_id_param.value.int_value AS variation_id AS variation_id,
The double
AS variation_id
is invalid SQL and will cause a syntax error. Just use a single alias, as shown above. This matches the correct usage in GrowthBook’s recommended queries for GA4/BigQuery when
variation_id
is stored as an integer [Forum example](https://linen.growthbook.io/t/30129167/u07fj89lffb-i-can-see-experiment-data-in-bigquery-but-in-gro). If you use the correct line and
variation_id_int
is populated in your data, your query should work as expected. If you still do not see results, double-check that all other filters and joins in your query are correct and that your experiment events have non-null
variation_id
values.
w
@brash-pillow-71627 this is the query now, but it doesn't get me results:
Copy code
-- Engaged Users (proportion)
WITH
  __rawExperiment AS (
    SELECT
      user_pseudo_id as anonymous_id,
      TIMESTAMP_MICROS(event_timestamp) as timestamp,
      experiment_id_param.value.string_value AS experiment_id,
      variation_id_param.value.int_value AS variation_id,
      geo.country as country,
      traffic_source.source as source,
      traffic_source.medium as medium,
      device.category as device,
      device.web_info.browser as browser,
      device.operating_system as os
    FROM
      `learning-heroes-bq`.`analytics_372696867`.`events_*`,
      UNNEST (event_params) AS experiment_id_param,
      UNNEST (event_params) AS variation_id_param
    WHERE
      (
        (_TABLE_SUFFIX BETWEEN '20250909' AND '20250909')
        OR (
          _TABLE_SUFFIX BETWEEN 'intraday_20250909' AND 'intraday_20250909'
        )
      )
      AND event_name = 'experiment_viewed'
      AND experiment_id_param.key = 'experiment_id'
      AND variation_id_param.key = 'variation_id'
      AND user_pseudo_id is not null
  ),
  __experimentExposures AS (
    -- Viewed Experiment
    SELECT
      e.anonymous_id as anonymous_id,
      cast(e.variation_id as string) as variation,
      CAST(e.timestamp as DATETIME) as timestamp
    FROM
      __rawExperiment e
    WHERE
      e.experiment_id = 'test-aa-httpsprogramaslearningheroescomia-heroesbp2'
      AND e.timestamp >= '2025-09-09 16:42:49'
      AND e.timestamp <= '2025-09-09 17:39:58'
  ),
  __experimentUnits AS (
    -- One row per user
    SELECT
      e.anonymous_id AS anonymous_id,
      (
        CASE
          WHEN count(distinct e.variation) > 1 THEN '__multiple__'
          ELSE max(e.variation)
        END
      ) AS variation,
      MIN(e.timestamp) AS first_exposure_timestamp
    FROM
      __experimentExposures e
    GROUP BY
      e.anonymous_id
  ),
  __distinctUsers AS (
    SELECT
      anonymous_id,
      variation,
      first_exposure_timestamp AS timestamp,
      date_trunc(first_exposure_timestamp, DAY) AS first_exposure_date
    FROM
      __experimentUnits
  ),
  __metric as ( -- Metric (Engaged Users)
    SELECT
      anonymous_id as anonymous_id,
      1 as value,
      CAST(m.timestamp as DATETIME) as timestamp
    FROM
      (
        SELECT
          TIMESTAMP_MICROS(event_timestamp) as timestamp,
          user_id,
          user_pseudo_id as anonymous_id,
          event_name,
          geo.country,
          device.category as device_category,
          traffic_source.source,
          traffic_source.medium,
          traffic_source.name as campaign,
          REGEXP_EXTRACT(
            (
              SELECT
                value.string_value
              FROM
                UNNEST (event_params)
              WHERE
                key = 'page_location'
            ),
            r'http[s]?:\/\/?[^\/\s]+\/([^?]*)'
          ) as page_path,
          (
            SELECT
              value.string_value
            FROM
              UNNEST (event_params)
            WHERE
              key = 'session_engaged'
          ) as session_engaged,
          event_value_in_usd,
          CAST(
            (
              SELECT
                value.int_value
              FROM
                UNNEST (event_params)
              WHERE
                key = 'ga_session_id'
            ) AS string
          ) as session_id,
          (
            SELECT
              value.int_value
            FROM
              UNNEST (event_params)
            WHERE
              key = 'engagement_time_msec'
          ) / 1000 as engagement_time
        FROM
          `learning-heroes-bq`.`analytics_372696867`.`events_*`
        WHERE
          (
            (_TABLE_SUFFIX BETWEEN '20250909' AND '20250909')
            OR (
              _TABLE_SUFFIX BETWEEN 'intraday_20250909' AND 'intraday_20250909'
            )
          )
      ) m
    WHERE
      (session_engaged = '1')
      AND m.timestamp >= '2025-09-09 16:42:49'
      AND m.timestamp <= '2025-09-09 17:39:58'
  ),
  __userMetricJoin as (
    SELECT
      d.variation AS variation,
      d.anonymous_id AS anonymous_id,
      (
        CASE
          WHEN m.timestamp >= d.timestamp
          AND m.timestamp <= '2025-09-09 17:39:58' THEN m.value
          ELSE NULL
        END
      ) as value
    FROM
      __distinctUsers d
      LEFT JOIN __metric m ON (m.anonymous_id = d.anonymous_id)
  ),
  __userMetricAgg as (
    -- Add in the aggregate metric value for each user
    SELECT
      umj.variation AS variation,
      umj.anonymous_id,
      COALESCE(MAX(umj.value), 0) as value
    FROM
      __userMetricJoin umj
    GROUP BY
      umj.variation,
      umj.anonymous_id
  )
  -- One row per variation/dimension with aggregations
SELECT
  m.variation AS variation,
  COUNT(*) AS users,
  SUM(COALESCE(m.value, 0)) AS main_sum,
  SUM(POWER(COALESCE(m.value, 0), 2)) AS main_sum_squares
FROM
  __userMetricAgg m
GROUP BY
  m.variation
b
A message from kapa.ai
Based on the knowledge sources, here are the most likely reasons your query is not returning results, and steps to debug: 1. Check for Data in the Raw Table First, confirm that your base query actually returns rows for the given date and experiment. Run this simplified query in BigQuery:
Copy code
sql    SELECT      user_pseudo_id,      TIMESTAMP_MICROS(event_timestamp) as timestamp,      experiment_id_param.value.string_value AS experiment_id,      variation_id_param.value.int_value AS variation_id    FROM      `learning-heroes-bq`.`analytics_372696867`.`events_*`,      UNNEST(event_params) AS experiment_id_param,      UNNEST(event_params) AS variation_id_param    WHERE      event_name = 'experiment_viewed'      AND experiment_id_param.key = 'experiment_id'      AND variation_id_param.key = 'variation_id'      AND user_pseudo_id IS NOT NULL      AND experiment_id_param.value.string_value = 'test-aa-httpsprogramaslearningheroescomia-heroesbp2'      AND (_TABLE_SUFFIX BETWEEN '20250909' AND '20250909'           OR _TABLE_SUFFIX BETWEEN 'intraday_20250909' AND 'intraday_20250909')    LIMIT 10
If this returns no rows, the issue is with the data itself (date, experiment_id, or event not present) or the filters. 2. Check for experiment_id Value Make sure the value in
experiment_id_param.value.string_value
exactly matches
'test-aa-httpsprogramaslearningheroescomia-heroesbp2'
. Typos or mismatches here are a common cause of no results [GA4 troubleshooting](https://docs.growthbook.io/kb/google-analytics/google-analytics-ga4-troubleshooting#common-issues-when-integrating-ga4-with-growthbook). 3. Check for Data Type Consistency Since you confirmed
variation_id_param.value.int_value
is populated, your query is correct to use it. Do not use
string_value
for
variation_id
in this case. 4. Relax Filters to Debug Try removing or commenting out the
experiment_id
filter and see if you get any rows. If you do, then the issue is with the experiment_id value or its type. 5. Check Date Range and Table Suffixes Ensure that the date and intraday suffixes match the data you have. If your data is not in the specified date, you will get no results [BigQuery troubleshooting](https://docs.growthbook.io/kb/google-analytics/google-big-query-bq-troubleshooting). 6. Check for Nulls in variation_id If you see rows but
variation_id
is null, your tracking may not be sending the value correctly, or the event parameter is not being set as expected. Summary: If your simplified query returns no rows, the problem is with the data (date, experiment_id, or event not present). If it returns rows, but your full query does not, the issue is likely with the filters or joins in the later CTEs. The knowledge sources emphasize checking the raw data first, then incrementally adding filters to isolate the issue [Forum example](https://linen.growthbook.io/t/30129167/u07fj89lffb-i-can-see-experiment-data-in-bigquery-but-in-gro). If you need further help, please share the output of the simplified query above.
w
@brash-pillow-71627 1) doesn't give me results
b
A message from kapa.ai
If the simplified query I provided does not return any results, this indicates that there are no matching
experiment_viewed
events in your BigQuery export for the specified date, experiment ID, and filters. This is a fundamental issue and is not specific to the structure of your more complex query. Based on the knowledge sources, here are the most likely reasons and next steps: 1. No Data for the Date or Experiment - There may be no
experiment_viewed
events for the date (
20250909
) or for the experiment ID you specified. Double-check that the experiment is running and that users are being exposed to it on that date. - Confirm that the experiment ID in your filter exactly matches what is being sent in your tracking (case, dashes, underscores, etc.) [GA4 troubleshooting](https://docs.growthbook.io/kb/google-analytics/google-analytics-ga4-troubleshooting#common-issues-when-integrating-ga4-with-growthbook). 2. Data Propagation Delay - If the experiment is recent, there may be a 24-48 hour delay before events appear in BigQuery. This is a known issue with GA4 exports [GA4 troubleshooting](https://docs.growthbook.io/kb/google-analytics/google-big-query-bq-troubleshooting#initial-sync-delay-for-new-ga4-properties). 3. Tracking Not Sending Events - If you do not see any
experiment_viewed
events, your tracking callback may not be firing, or the event is not being sent to GA4/BigQuery as expected. You should verify in your application that the event is being pushed and that both
experiment_id
and
variation_id
are present [Forum example](https://linen.growthbook.io/t/16319175/hi-all-we-re-just-getting-started-with-a-b-testing-using-the). 4. Incorrect Table Suffix or Dataset - Double-check that the dataset and table names in your query match your actual BigQuery export. If you have multiple GA4 properties or datasets, you may be querying the wrong one [Forum example](https://linen.growthbook.io/t/29148772/hi-i-was-able-to-succesfully-setup-an-experiment-a-b-test-un). What to do next: - Remove the experiment ID filter and see if any
experiment_viewed
events exist for that date. - Remove the date filter and see if any
experiment_viewed
events exist at all. - If you still get no results, check your tracking implementation and ensure events are being sent and received as expected. If after these steps you still do not see any data, the knowledge sources do not provide further troubleshooting steps beyond verifying your tracking and data export setup. You may need to review your GA4 and GrowthBook integration to ensure events are being tracked and exported correctly.
w
@brash-pillow-71627 chatgpt gave me this query and gave me results:
Copy code
-- Ajustá el project/dataset si hace falta
WITH base AS (
  SELECT
    user_pseudo_id,
    TIMESTAMP_MICROS(event_timestamp) AS ts,
    event_name,
    -- Extrae valores tolerando tipos (string/int/double)
    (SELECT ep.value.string_value
     FROM UNNEST(event_params) ep
     WHERE ep.key = 'experiment_id')                                         AS experiment_id_str,
    (SELECT
       COALESCE(
         CAST(ep.value.int_value    AS INT64),
         SAFE_CAST(ep.value.string_value AS INT64),
         CAST(ep.value.double_value AS INT64)
       )
     FROM UNNEST(event_params) ep
     WHERE ep.key = 'variation_id')                                         AS variation_id_int
  FROM `learning-heroes-bq.analytics_372696867.events_*`
  WHERE event_date = '20250909'
    AND event_name IN ('experiment_viewed','experiment_impression','experiment_exposure')
    AND EXISTS (
      SELECT 1
      FROM UNNEST(event_params) ep
      WHERE ep.key = 'experiment_id'
        AND ep.value.string_value = 'test-aa-httpsprogramaslearningheroescomia-heroesbp2'
    )
)
SELECT
  user_pseudo_id,
  ts AS timestamp,
  experiment_id_str AS experiment_id,
  variation_id_int  AS variation_id
FROM base
WHERE experiment_id_str = 'test-aa-httpsprogramaslearningheroescomia-heroesbp2'
LIMIT 10;
b
A message from kapa.ai
Thank you for sharing the query that returns results. Based on the knowledge sources, here’s what’s happening and how it relates to GrowthBook and GA4/BigQuery integration: Why does this query work? - Your query is robust: it extracts
variation_id
by trying
int_value
, then (safely) casting
string_value
, then
double_value
. This approach tolerates inconsistent data types in GA4 event parameters, which is a known issue in GA4/BigQuery exports. - The query also uses a subquery in the
SELECT
to extract the correct
experiment_id
and
variation_id
from the
event_params
array, which is the recommended way to handle GA4’s flexible schema. What does this mean for your GrowthBook queries? - If your GrowthBook assignment or metric queries are only using
variation_id_param.value.int_value
(or only
string_value
), they may miss events where the type is not consistent, resulting in missing data. - The knowledge sources confirm that type mismatches are a common cause of missing experiment data in GrowthBook, and recommend ensuring your queries match the actual data type in your GA4 export [Forum example](https://linen.growthbook.io/t/30129167/u07fj89lffb-i-can-see-experiment-data-in-bigquery-but-in-gro). What should you do? - Update your GrowthBook Experiment Assignment Query to use a similar approach as your working query: extract
variation_id
using
COALESCE
across possible types (
int_value
,
string_value
,
double_value
), and ensure you are unnesting and filtering event parameters as in your working query. - This will make your GrowthBook queries more robust to data type inconsistencies and should resolve the issue of missing results. Example for GrowthBook Experiment Assignment Query:
Copy code
sql SELECT   user_pseudo_id as anonymous_id,   TIMESTAMP_MICROS(event_timestamp) as timestamp,   (SELECT ep.value.string_value    FROM UNNEST(event_params) ep    WHERE ep.key = 'experiment_id') AS experiment_id,   (SELECT      COALESCE(        CAST(ep.value.int_value AS INT64),        SAFE_CAST(ep.value.string_value AS INT64),        CAST(ep.value.double_value AS INT64)      )    FROM UNNEST(event_params) ep    WHERE ep.key = 'variation_id') AS variation_id,   geo.country as country,   device.category as device,   device.web_info.browser as browser FROM   `learning-heroes-bq`.`analytics_372696867`.`events_*` WHERE   event_name = 'experiment_viewed'   AND (_TABLE_SUFFIX BETWEEN '20250909' AND '20250909'        OR _TABLE_SUFFIX BETWEEN 'intraday_20250909' AND 'intraday_20250909')   AND user_pseudo_id IS NOT NULL
This approach is consistent with the troubleshooting and best practices described in the knowledge sources for GrowthBook and GA4/BigQuery integrations [GA4 troubleshooting](https://docs.growthbook.io/kb/google-analytics/google-analytics-ga4-troubleshooting#common-issues-when-integrating-ga4-with-growthbook). If you continue to see issues, double-check your event tracking implementation to ensure both
experiment_id
and
variation_id
are always sent and populated.