GA4 events
A Google Analytics 4 export is one table per day with every event's parameters packed into a repeated STRUCT. Querylab.io recognises the dataset, collapses the shards into one node, and shows which events and parameters are actually in the data (sampled for free), with the UNNEST snippets ready to paste.
How the export is recognised
A dataset named analytics_<digits> is treated as a GA4 export; the digits are the property ID. Inside it, events_YYYYMMDD is the daily export and events_intraday_YYYYMMDD the streaming export for the current day. Nothing is configured — the names are the signal.
The shard group
Any table whose name ends in a date (_YYYYMMDD, _YYYYMM, _YYYYMMDDHH) is grouped with its siblings into a single tree node, events (412). This applies to every sharded table, not just GA4. Opening the node shows the schema of the newest shard and a Sharded Table Info group on the Details tab:
Sharded Table Info
SELECT * FROM `ace-analytics.analytics_388475286.events_*` WHERE _TABLE_SUFFIX BETWEEN '20260801' AND '20260828'Table info
ace-analytics.analytics_388475286.events_*The wildcard query has Copy to clipboard and Open in new tab buttons; Discover partitions generates an INFORMATION_SCHEMA.TABLES query that lists every shard with its size. Row counts and bytes in Storage info are summed across the shards.
Seeing which events are in the data
Which events are in the table, from a free 1,000-row sample:
| Event Name⏷ | Description⏷ | Count (sampled)⏷ | % of Sample⏷ | |
|---|---|---|---|---|
| 1 | page_view | A page was viewed | 523 | 52.3% |
| 2 | session_start | A session began | 141 | 14.1% |
| 3 | user_engagement | User engaged with the page for at least 10 seconds | 118 | 11.8% |
| 4 | scroll | User scrolled to the bottom of the page | 96 | 9.6% |
| 5 | first_visit | First visit to the site or app | 44 | 4.4% |
| 6 | purchase | A purchase was completed | 3 | 0.3% |
Descriptions come from Google’s documentation for the automatically collected and recommended events; custom events show no description. Counts are of the sample, so treat them as proportions. Run query to get all values shows the estimated cost, then replaces the sample with exact counts — the % of Sample column disappears because it no longer applies.
Pulling parameters out of event_params
The keys inside event_params, with the value type each one uses:
| Parameter Key⏷ | Description⏷ | Value Type⏷ | Source⏷ | Count⏷ | Insert⏷ | |
|---|---|---|---|---|---|---|
| 1 | page_location | Full URL of the page | string_value | Built-in | 523 | ⤵ |
| 2 | page_title | Title of the page | string_value | Built-in | 523 | ⤵ |
| 3 | ga_session_id | Session identifier | int_value | Built-in | 1000 | ⤵ |
| 4 | engagement_time_msec | Engagement time in milliseconds | int_value | Built-in | 617 | ⤵ |
| 5 | value | Monetary value of the event | double_value | Built-in | 3 | ⤵ |
| 6 | plan_tier | null | string_value | Sampled | 41 | ⤵ |
Source tells you where the row came from: Built-in parameters are the ones GA4 documents (they are listed even if the sample did not contain them, when Show all built-in params is on); Sampled parameters were found in the data and are usually your custom ones. A custom parameter that occurs rarely may be missing from a 1,000-row sample — the banner says so, and Run query to get all values fixes it.
The tab’s main output is SQL. Clicking a row’s Insert button (or Copy SQL) produces the subquery for that key, typed correctly:
(SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'page_location') AS page_location Select several rows and Insert N Selected inserts them as a comma-separated list in the active query tab. The Snippets menu inserts a template instead — Extract String, Extract Integer, Extract Double, Extract Float, Extract Any Type (a COALESCE over all four value columns) or Extract Multiple (Template).
Writing the query
Filter on _TABLE_SUFFIX and event_name first; both prune before any bytes are read. Then unnest what you need:
SELECT event_date, event_name, (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'page_location') AS page_location, (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id') AS session_id FROM `ace-analytics.analytics_388475286.events_*` WHERE _TABLE_SUFFIX BETWEEN '20260801' AND '20260828' AND event_name = 'page_view'
The Schema tab fills in Google’s description for the export’s built-in columns when the table itself has none, so columns such as user_pseudo_id or privacy_info come with an explanation.
Extra menu items on a GA4 dataset
Right-click a GA4 dataset for two extra entries under a Google Analytics 4 divider:
- GA4 Templates — ready-made queries for the property: Events by Date, Top Events, Daily Active Users, Page Views by URL, User Acquisition, User Engagement, Users by Device, Users by Geography, Revenue by Item, Purchase Funnel, Transactions, and explorers for
event_params,user_properties,itemsand the expanded-export tables. Each opens in a new tab with the dataset filled in. - GA4 Model Generator — opens a tab that generates analysis-ready tables from the raw export: session-scoped attribution with gclid correction, channel grouping, custom parameter columns, conversion events, RFM segments, with multi-property support and a configurable date range.
The dataset’s Details tab also shows the Property ID, whether Events Export and Intraday Streaming are present, the Last Export Date, and a View in Google Analytics link.