YouTube Analytics model

Viewer demographics daily

Who watches each channel: views split by age group and gender per day, the "Age" and "Gender" cards of the YouTube Studio Audience tab.

Grain
date_day x channel_id x age_group x gender
Built from
  1. 2
    Raw tables
  2. 2
    Staging
  3. 1
    Core
  4. 1
    Analytics
Reads from YouTube Analytics
channel_basic_a3channel_demographics_a1
Ships as
Weld and dbt SQL, open source on GitHub
core.youtube_analytics.viewer_demographics_daily
1-- core.youtube_analytics.viewer_demographics_daily
2-- Who watches each channel: views split by age group and gender per day, the
3-- "Age" and "Gender" cards of the YouTube Studio Audience tab.
4--
5-- Grain: date_day x channel_id x age_group x gender. Dates are Pacific Time.
6-- Depends on: staging.youtube_analytics.channel_demographics, .channel_basic
7--
8-- YouTube delivers demographics as percentages per slice (video, country,
9-- subscribed status, live or on demand), not as counts. Adding those
10-- percentages up across slices gives a number with no meaning: a slice with
11-- 3 views would count as much as one with 30,000. Here each percentage is
12-- multiplied by the views of its own slice from the activity report, which
13-- turns it into estimated views; those can be summed and divided again.
14--
15-- estimated_views only covers signed-in viewers whose age and gender YouTube
16-- knows, and slices that YouTube withheld from either report for privacy drop
17-- out. Compare shares, not totals, with Studio, and re-derive the share from
18-- summed estimated_views for a longer period.
19
20WITH slice_views AS (
21    -- The activity report is already one row per slice; the SUM only guards
22    -- against a slice that arrives twice.
23    SELECT
24        date_day,
25        channel_id,
26        video_id,
27        live_or_on_demand,
28        subscribed_status,
29        country_code,
30        SUM(views) AS views
31    FROM {{staging.youtube_analytics.channel_basic}}
32    GROUP BY 1, 2, 3, 4, 5, 6
33),
34
35weighted AS (
36    SELECT
37        d.date_day,
38        d.channel_id,
39        d.age_group,
40        d.gender,

This model and the 3 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.

YouTube delivers demographics as percentages per slice (video, country, subscribed status, live or on demand), not as counts. Adding those percentages up across slices gives a number with no meaning: a slice with 3 views would count as much as one with 30,000. Here each percentage is multiplied by the views of its own slice from the activity report, which turns it into estimated views; those can be summed and divided again. estimated_views only covers signed-in viewers whose age and gender YouTube knows, and slices that YouTube withheld from either report for privacy drop out. Compare shares, not totals, with Studio, and re-derive the share from summed estimated_views for a longer period.

Raw tables it reads

  • raw.youtube_analytics.channel_basic_a3
  • raw.youtube_analytics.channel_demographics_a1

Put YouTube Analytics in front
of your agents.

Connect YouTube Analytics, deploy the models, and ask questions in Claude, Cursor or ChatGPT. Free for 14 days, no credit card.