Skip to content

Instantly share code, notes, and snippets.

select
-- day of week, starting with Sunday (dimension)
format_date('%w',parse_date("%Y%m%d",event_date)) as day_of_week,
-- hour (dimension)
format("%02d",extract(hour from timestamp_micros(event_timestamp))) as hour,
(select value.string_value from unnest(event_params) where key = 'page_location') as page_path,
count(event_name) as sessions
from
-- change this to your google analytics 4 export location in bigquery
`yourproject.analytics_1234567.events_*`
@nicobrx
nicobrx / ga4_page_value.sql
Last active June 1, 2024 10:03
Gets a page_value metric from GA4 data in BigQuery that is similar to the Universal Analytics Page Value metric: https://support.google.com/analytics/answer/2695658 To use the query, replace the table references in lines 15 and 26 with your GA4 events table. Make sure to replace the table's date suffix with '*' so the query runs across date part…
-- set dates here so we don't have to update them in multiple places
with dates as (
select
'20230812' as start_date,
-- the next line gets yesterday
format_date('%Y%m%d',date_sub(current_date(), interval 1 day)) as end_date
),
-- get all events with event values
p as (
--Looker Studio BigQuery custom query to get sessions per user
with s as (select distinct
user_pseudo_id,
concat(user_pseudo_id,(SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id')) AS session_id,
timestamp_micros(event_timestamp) as timestamp
from `yourbqproject.analytics_1234567.events_*`
where _table_suffix between @DS_START_DATE and @DS_END_DATE
and event_name = 'session_start')
@nicobrx
nicobrx / ga4_average_engagement_time_per_page.sql
Created June 8, 2023 04:09
Query for getting average engagement time per page from GA4 BigQuery data.
SELECT
page_location,
SUM(engagement_time_seconds) AS engagement_time_seconds,
SUM(page_views) AS page_views,
SAFE_DIVIDE( SUM(engagement_time_seconds), SUM(page_views) ) AS average_engagement_time_per_page
FROM (
SELECT
(
SELECT
value.string_value
SELECT
event_date,
COUNT(DISTINCT(session_id)) AS sessions,
SUM(ga4_resource_page_views) AS ga4_resource_page_views
FROM (
SELECT
CONCAT(user_pseudo_id,(SELECT value.int_value FROM UNNEST(event_params) WHERE KEY = 'ga_session_id')) AS session_id,
COUNT((SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'page_location'
AND value.string_value LIKE 'https://twooctobers.com/blog/ga4-resources/%')) AS ga4_resource_page_views,
PARSE_DATE('%Y%m%d',event_date) AS event_date
<script>
if(!(window.ga && ga.create)) {
dataLayer.push({'event': 'gaNotLoaded'});
}
</script>
<script>
/*
* adapted from https://developers.google.com/analytics/devguides/collection/analyticsjs/cross-domain#iframes
* I wrapped the whole thing in a setTimeout, so I could observe the delayed execution time
* of the GA function in the JavaScript console, using the GA debugger Chrome plugin.
* alternatively, you could just wrap the frameWindow.postMessage in a setTimeout
*/
setTimeout(function(){
ga(function(tracker) {
<script>
/*
* adapted from https://developers.google.com/analytics/devguides/collection/analyticsjs/cross-domain#iframes
* I include the GA object reference in my script, so that one version of
* the script works whether served in an iFrame or on a standalone page.
* I usually have to rely on the 3rd-party vendor to implement the code, so
* I like to keep implementation as simple as possible.
*/
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
/**
* Writes a list of AdWords accounts in an MCC to a Google Sheet
* Useful in conjunction with scripts that run on batches of accounts
*
* The label-batching portion of this script was adapted from:
* http://magentosupport.help/knowledgebase/using-labels-to-executeinparallel-exceeding-the-50-account-limit/
*/
var TIMEZONE = 'MST';
var TODAY_STR = Utilities.formatDate(new Date(), TIMEZONE, 'yyyy-MM');
@nicobrx
nicobrx / to_util
Last active June 6, 2024 21:45
Google Apps Script utility functions for working with 2D arrays in Sheets/tabs, plus a few other miscellanea. The 2D functions depend on the first row of a tab being column headers and each row below the first row having the same number of columns as the first row.
/*
updated 2018-04-28
source lives here: https://gist.github.com/nicobrx/2ecd6fc9ca733dcd883afebba5cf200e
standalone script ID for use as a library: 1gZ78JObyrYiH0njoZ86fQ2NgMwavUgiXVhRDrIFetPZL256e31PSNiHq
Functions included here:
Sheets data array and object functions
objectifySheet(sheet,propertyNames,newPropertyNames) - Takes a sheet with a header row and converts it into an array of objects
arrayFromSheet(sheet,propertyNames,newPropertyNames) - creates an array from a sheet, can specify column headers