Data Warehouse example queries
This section contains some example queries which you can run using your Data Warehouse.
Gameplay and progression
List of players ranked by game progress and score
WITH completed_runs AS (
SELECT
user_id,
progression_1 AS world_name,
score,
checkpoint
FROM `checkpoints.progression_checkpoint`
WHERE progression_status = 'complete'
AND game_id = 1234
AND checkpoint = DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY)
),
ranked_scores AS (
SELECT
user_id,
world_name,
score,
RANK() OVER (PARTITION BY world_name ORDER BY score DESC) AS score_rank
FROM completed_runs
)
SELECT
world_name,
user_id,
score
FROM ranked_scores
WHERE score_rank = 1
ORDER BY world_name;
How far users are in the game
WITH completed_worlds AS (
SELECT
user_id,
progression_1 AS world_name,
checkpoint,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY checkpoint DESC) AS rn
FROM `checkpoints.progression_checkpoint`
WHERE progression_status = 'complete'
AND game_id = 1234
AND checkpoint = DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY)
)
SELECT
user_id,
world_name,
checkpoint AS last_completed_at
FROM completed_worlds
WHERE rn = 1
ORDER BY last_completed_at DESC;
Live ops and In-game economies
A/B Test revene per user
DECLARE target_ab_test_id STRING DEFAULT ''; -- Replace with your A/B test ID
SELECT
user_id,
SUM(revenue_usd) AS total_revenue_usd
FROM `checkpoints.player_checkpoint`
WHERE ab_test_id = target_ab_test_id
AND game_id = 1234
GROUP BY user_id
ORDER BY total_revenue_usd DESC;
Most popular resources sourced per day
SELECT
DATE(checkpoint) AS day,
resource_currency,
SUM(resource_amount_sum) AS total_sourced
FROM `checkpoints.resource_checkpoint`
WHERE flow_type = 'Source'
AND game_id = 1234 -- assuming game_id is needed here too
AND checkpoint = DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY)
GROUP BY day, resource_currency
ORDER BY day DESC, total_sourced DESC;
Monetization and revenue
Top revenue generating currency
SELECT
currency, SUM(amount_usd) as total_in_usd_cents
FROM
`checkpoints.payment_checkpoint`
WHERE
checkpoint = "2025-10-01"
AND game_id = 1234
GROUP BY 1
ORDER BY 2 DESC
LIMIT 1
Player activity and Retention
Retention
WITH install_data AS (
SELECT
user_id,
install_ts as install_date,
checkpoint as snapshot_date,
DATE_DIFF(checkpoint, install_ts, DAY) as days_since_install
FROM
`checkpoints.player_checkpoint`
WHERE
game_id = 1234
AND checkpoint →= DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)
AND install_ts →= DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)
),
returning_users AS
(
SELECT
install_date,
COUNT(DISTINCT user_id) as number_of_installs,
COUNT(DISTINCT IF(days_since_install = 1, user_id, NULL)) as returning_d1,
COUNT(DISTINCT IF(days_since_install = 2, user_id, NULL)) as returning_d2,
COUNT(DISTINCT IF(days_since_install = 3, user_id, NULL)) as returning_d3,
COUNT(DISTINCT IF(days_since_install = 4, user_id, NULL)) as returning_d4,
COUNT(DISTINCT IF(days_since_install = 5, user_id, NULL)) as returning_d5,
COUNT(DISTINCT IF(days_since_install = 6, user_id, NULL)) as returning_d6,
COUNT(DISTINCT IF(days_since_install = 7, user_id, NULL)) as returning_d7,
FROM
install_data
GROUP BY 1
)
SELECT
install_date,
number_of_installs,
SAFE_DIVIDE(returning_d1, number_of_installs) as retention_d1,
SAFE_DIVIDE(returning_d2, number_of_installs) as retention_d2,
SAFE_DIVIDE(returning_d3, number_of_installs) as retention_d3,
SAFE_DIVIDE(returning_d4, number_of_installs) as retention_d4,
SAFE_DIVIDE(returning_d5, number_of_installs) as retention_d5,
SAFE_DIVIDE(returning_d6, number_of_installs) as retention_d6,
SAFE_DIVIDE(returning_d7, number_of_installs) as retention_d7,
FROM
returning_users
ORDER BY 1
Ad views per day
SELECT
DATE(checkpoint) AS date,
SUM(ad_impressions) AS total_ad_views
FROM
`checkpoints.adactivity_checkpoint`
WHERE
game_id = 1234
AND checkpoint = DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY) -- only yesterday's data
GROUP BY
date
ORDER BY
date DESC;
Most popular hours to play
SELECT
TIMESTAMP_TRUNC(event_arrival_ts, HOUR) AS hour,
SUM(publisher_revenue_usd_cents) AS revenue_usd
FROM
`events.impression_event`
WHERE
event_arrival_ts →= TIMESTAMP_SUB(TIMESTAMP_TRUNC(CURRENT_TIMESTAMP(), DAY), INTERVAL 1 DAY)
AND event_arrival_ts < TIMESTAMP_TRUNC(CURRENT_TIMESTAMP(), DAY)
AND game_id = 1234
GROUP BY
hour
ORDER BY
hour;
Technical performance
Devices sending the most errors
SELECT
device,
sum(error_error_count) as total_errors
-- sum(error_critical_count)
-- sum(error_warning_count)
-- sum(error_info_count)
-- sum(error_debug_count)
FROM
`checkpoints.player_checkpoint`
WHERE
checkpoint = "2025-10-01"
AND game_id = 1234
GROUP BY 1
ORDER BY 2 DESC
LIMIT 1