PRO SQL Modules
SQL Basics1h 20m • 4 lessons
Multiple Tables1h 40m • 5 lessons
Query Restructuring40m • 2 lessons
Data Transformation1h 40m • 5 lessons
Analytical SQL2h • 6 lessons
INNER JOIN

Dan Lee
Lesson Objectives
By the end of this lesson, you will:
- Learn how to combine data from multiple tables using INNER JOIN
- Understand how to match related records on a common key
- Write SQL queries to analyze Google Ads campaign performance by merging user and campaign data
🎬 Scenario: Understanding Google Ads Performance
Your new manager at Google Ads, Jordan, is analyzing advertising performance and wants to connect user accounts with their ad campaigns.
I need a report that shows each company’s total ad budget alongside their account details. Can you join the relevant tables for me?
Your task is to join the google_ads_users and google_ads_campaigns tables to create a comprehensive report on ad spending.
Table: google_ads_campaigns
campaign_id | user_id | campaign_name | ad_type | start_date | end_date | budget | impressions | clicks | conversions |
---|---|---|---|---|---|---|---|---|---|
1 | 1 | “Growth Hackers Special” | “Search” | “2024-01-10T00:00:00” | “2024-02-10T00:00:00” | 5000 | 500000 | 12000 | 800 |
2 | 2 | “BigTech Awareness” | “Display” | “2024-01-05T00:00:00” | “2024-02-20T00:00:00” | 20000 | 2000000 | 50000 | 3000 |
3 | 3 | “Ecom Holiday Sales” | “Shopping” | “2023-11-15T00:00:00” | “2024-01-15T00:00:00” | 10000 | 750000 | 22000 | 1500 |
4 | 4 | “Fashion Hub Summer” | “Video” | “2024-02-01T00:00:00” | “2024-03-01T00:00:00” | 15000 | 900000 | 18000 | 1200 |
5 | 5 | “HealthyLife Brand Push” | “Search” | “2024-01-20T00:00:00” | “2024-03-10T00:00:00” | 8000 | 600000 | 15000 | 900 |
Table: google_ads_users
user_id | name | company | country | signup_date | ad_spend_total | is_active | |
---|---|---|---|---|---|---|---|
1 | “Alice Johnson” | “alice@startupx.com” | “StartupX” | “USA” | “2021-06-15T00:00:00” | 50000 | true |
2 | “Bob Smith” | “bob@bigtech.com” | “BigTech Corp” | “Canada” | “2020-03-20T00:00:00” | 200000 | true |
3 | “Charlie Lee” | “charlie@ecomstore.com” | “EcomStore” | “UK” | “2019-11-01T00:00:00” | 75000 | false |
4 | “David Kim” | “david@fashionhub.com” | “FashionHub” | “Germany” | “2022-05-30T00:00:00” | 120000 | true |
5 | “Emma Garcia” | “emma@healthylife.com” | “HealthyLife” | “Mexico” | “2023-02-12T00:00:00” | 30000 | true |
1. Understanding INNER JOIN
An INNER JOIN combines rows from two tables when there is a matching value in both tables.
Syntax
1SELECT table1.column1, table2.column2
2FROM table1
3INNER JOIN table2
4ON table1.common_key = table2.common_key;
- INNER JOIN only returns rows where both tables have matching values on the common key.
- If there is no match, the row is excluded from the result.
2. Joining Google Ads Users with Campaign Data
To analyze company spending, we need to join:
- google_ads_users (user account details)
- google_ads_campaigns (advertising campaign details)
The common key is user_id, which links each campaign to a user.
Example Query: Merging User and Campaign Data
1SELECT u.user_id, u.name, u.company, u.country, c.campaign_name, c.budget
2FROM google_ads_users u
3INNER JOIN google_ads_campaigns c
4ON u.user_id = c.user_id;
user_id | name | company | country | campaign_name | budget |
---|---|---|---|---|---|
1 | Alice Johnson | StartupX | USA | Growth Hackers Special | 5000 |
2 | Bob Smith | BigTech Corp | Canada | BigTech Awareness | 20000 |
3 | Charlie Lee | EcomStore | UK | Ecom Holiday Sales | 10000 |
4 | David Kim | FashionHub | Germany | Fashion Hub Summer | 15000 |
5 | Emma Garcia | HealthyLife | Mexico | HealthyLife Brand Push | 8000 |
What’s Happening?
- INNER JOIN connects users and their campaigns by user_id.
- If a user has multiple campaigns, their details repeat in the result.
- Users without campaigns are excluded from the result.
3. Joining Campaigns with Click Data
To analyze campaign click performance, we need to join:
- google_ads_campaigns (campaign details)
- google_ads_clicks (click data)
The common key is campaign_id, which links clicks to campaigns.
Example Query: Joining Campaigns with Clicks
1SELECT c.campaign_id, c.campaign_name, cl.click_id, cl.device_type, cl.converted
2FROM google_ads_campaigns c
3INNER JOIN google_ads_clicks cl
4ON c.campaign_id = cl.campaign_id;
campaign_id | campaign_name | click_id | device_type | converted |
---|---|---|---|---|
1 | “Growth Hackers Special” | 1 | “Mobile” | false |
1 | “Growth Hackers Special” | 2 | “Desktop” | true |
2 | “BigTech Awareness” | 3 | “Tablet” | false |
2 | “BigTech Awareness” | 4 | “Mobile” | true |
3 | “Ecom Holiday Sales” | 5 | “Desktop” | false |
3 | “Ecom Holiday Sales” | 6 | “Mobile” | true |
4 | “Fashion Hub Summer” | 7 | “Mobile” | false |
4 | “Fashion Hub Summer” | 8 | “Tablet” | false |
5 | “HealthyLife Brand Push” | 9 | “Desktop” | true |
5 | “HealthyLife Brand Push” | 10 | “Mobile” | false |
2 | “BigTech Awareness” | 11 | “Mobile” | true |
1 | “Growth Hackers Special” | 12 | “Tablet” | false |
What’s Happening?
- INNER JOIN links each click to the campaign that generated it.
- If a campaign has no recorded clicks, it is excluded from the results.
✍️ SQL Exercises
Exercise 1: Merging User and Campaign Data
Jordan needs a report showing each company’s total ad budget and country.
Filter condition:
- Retrieve company name, country, and total budget for each user.
- Sort by budget in descending order.
company | country | budget |
---|---|---|
BigTech Corp | Canada | 20000 |
FashionHub | Germany | 15000 |
EcomStore | UK | 10000 |
HealthyLife | Mexico | 8000 |
StartupX | USA | 5000 |
Write an SQL query to return the requested data.
Exercise 2: Analyzing Campaign Click Data
Jordan wants to analyze clicks per campaign.
Filter condition:
- Retrieve campaign name, click ID, and device type.
- Sort by campaign_id in ascending order.
campaign_name | click_id | device_type |
---|---|---|
“Growth Hackers Special” | 1 | “Mobile” |
“Growth Hackers Special” | 2 | “Desktop” |
“Growth Hackers Special” | 12 | “Tablet” |
“BigTech Awareness” | 3 | “Tablet” |
“BigTech Awareness” | 4 | “Mobile” |
“BigTech Awareness” | 11 | “Mobile” |
“Ecom Holiday Sales” | 5 | “Desktop” |
“Ecom Holiday Sales” | 6 | “Mobile” |
“Fashion Hub Summer” | 7 | “Mobile” |
“Fashion Hub Summer” | 8 | “Tablet” |
“HealthyLife Brand Push” | 9 | “Desktop” |
“HealthyLife Brand Push” | 10 | “Mobile” |
Write an SQL query to return the requested data.