Country performance daily
Daily campaign performance by country, Google's "Locations > user locations" report with names attached.
- Grain
- date_day x account_id x campaign_id x country_criterion_id x location_type
- Built from
- 4Raw tables
- 4Staging
- 1Core
- 1Analytics
- Reads from Google Ads
- accountad_group_country_statscampaigngeo_target
- Ships as
- Weld and dbt SQL, open source on GitHub
1-- core.google_ads.country_performance_daily
2-- Daily campaign performance by country, Google's "Locations > user locations"
3-- report with names attached.
4--
5-- Grain: date_day x account_id x campaign_id x country_criterion_id x location_type.
6-- Currency: the account's. Depends on: staging.google_ads.ad_group_country_stats,
7-- .geo_target, .campaign, .account
8--
9-- location_type says how the user matched the country: LOCATION_OF_PRESENCE
10-- (physically there) or AREA_OF_INTEREST (searching for it). It stays in the
11-- grain. Filter to one type for a "spend by country" view; check the total
12-- against the campaign report before summing both types together.
13--
14-- Built from ad group rows, so campaigns without ad groups (Performance Max)
15-- are not in it.
16
17WITH daily AS (
18 SELECT
19 date_day,
20 account_id,
21 campaign_id,
22 country_criterion_id,
23 location_type,
24 MAX(campaign_name) AS report_campaign_name,
25 SUM(spend) AS spend,
26 SUM(impressions) AS impressions,
27 SUM(clicks) AS clicks,
28 SUM(conversions) AS conversions,
29 SUM(conversion_value) AS conversion_value
30 FROM {{staging.google_ads.ad_group_country_stats}}
31 GROUP BY 1, 2, 3, 4, 5
32)
33
34SELECT
35 d.date_day,
36 d.account_id,
37 acc.account_name,
38 acc.currency,
39 d.campaign_id,
40 COALESCE(c.campaign_name, d.report_campaign_name) AS campaign_name,This model and the 5 it depends on. Deploy them together; refs like {{staging.…}} resolve to the matching folders in Weld, and the dbt view uses source() and ref().
How it counts. And where it stops.
location_type says how the user matched the country: LOCATION_OF_PRESENCE (physically there) or AREA_OF_INTEREST (searching for it). It stays in the grain. Filter to one type for a "spend by country" view; check the total against the campaign report before summing both types together. Built from ad group rows, so campaigns without ad groups (Performance Max) are not in it.
Raw tables it reads
- raw.google_ads.account
- raw.google_ads.ad_group_country_stats
- raw.google_ads.campaign
- raw.google_ads.geo_target
More Google Ads models
Put Google Ads in front
of your agents.
Connect Google Ads, deploy the models, and ask questions in Claude, Cursor or ChatGPT. Free for 14 days, no credit card.