Learn SQL/Intermediate/Joins/SQL One-to-Many Relationships

SQL One-to-Many Relationships

One row on the 'one' side can relate to several rows on the 'many' side — by far the most common relationship pattern in real databases.

What & Why

A one-to-many relationship lets one parent row correspond to several child rows while each child points to one parent. One marketing.campaigns row can have many marketing.leads rows, and each lead stores its campaign in campaign_id.

See How It Works

BUSINESS QUESTION

Marketing lists the leads belonging to each campaign.

idnamechannelspendstart_dateend_datestatustarget_segment
1Spring Launchgoogle_ads55000.002024-01-152024-03-31activesmb
2Retention Webinaremail45000.002024-02-102024-04-15activeenterprise
3Finance Retargetinglinkedin50000.002024-03-122024-05-31activeenterprise
4Enterprise Searchgoogle_ads60000.002024-04-012024-06-30activeenterprise
idcampaign_idemailcreated_atqualified_atconverted_atlead_scoresourcecountry
3011ana@example.com2024-01-21 09:10:00+002024-01-22 11:00:00+002024-02-02 10:00:00+0086google_adsUS
3021ben@example.com2024-01-24 12:40:00+00NULLNULL52google_adsCA
3032chloe@example.com2024-02-16 08:30:00+002024-02-18 14:20:00+00NULL74emailGB
3043dev@example.com2024-03-20 17:15:00+002024-03-21 09:00:00+002024-04-04 16:00:00+0091linkedinUS
Trace the relationship row by row1× speed
marketing.campaigns
idname
1Spring Launch
2Retention Webinar
3Finance Retargeting
4Enterprise Search
campaign.id = lead.campaign_id
marketing.leads
idcampaign_idsource
3011google_ads
3021google_ads
3032email
3043linkedin
Result set · 1 rows
campaign_namelead_idsource
Spring Launch301google_ads

Lead 301 matches campaign 1.

EXAMPLE QUERY
SELECT
  c.name AS campaign_name,
  l.id AS lead_id,
  l.source
FROM marketing.campaigns c
JOIN marketing.leads l ON l.campaign_id = c.id
ORDER BY campaign_name, lead_id;
Now You Try

Practice this concept

Marketing lists every lead beside its parent campaign.

Available schema
marketing

Prefix tables with marketing.table_name.

campaign_namelead_idsource
marketing.campaigns
ColumnType
idinteger
nametext
channeltext
spendnumeric
start_datedate
end_datedate
statustext
target_segmenttext
legacy_idtext
marketing.leads
ColumnType
idinteger
campaign_idinteger
emailtext
created_attimestamp with time zone
qualified_attimestamp with time zone
converted_attimestamp with time zone
lead_scoreinteger
sourcetext
countrytext
archive_statustext
query.sql
Intermediate business practice

Sign up free to try it on a real business scenario