Google Ads model

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
  1. 4
    Raw tables
  2. 4
    Staging
  3. 1
    Core
  4. 1
    Analytics
Reads from Google Ads
accountad_group_country_statscampaigngeo_target
Ships as
Weld and dbt SQL, open source on GitHub
core.google_ads.country_performance_daily
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().

Notes

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

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.