SQL RIGHT JOIN

The mirror image of LEFT JOIN — keeps every row from the RIGHT table, filling in NULL for any unmatched left-side rows.

What & Why

RIGHT JOIN flips which side is fully preserved — every row from the right table survives, and unmatched rows get NULL on the left side instead. Most people default to always writing LEFT JOIN (just swapping table order) for consistency, but it's worth recognizing RIGHT JOIN when reading someone else's query.

See How It Works

BUSINESS QUESTION

Marketing wants every campaign in the result, including campaigns that have no lead rows, using RIGHT JOIN to preserve campaigns.

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
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
Trace the relationship row by row1× speed
marketing.leads
idcampaign_idsource
3011google_ads
3021google_ads
3032email
3043linkedin
lead.campaign_id = campaign.id
marketing.campaigns · preserved right table
idname
1Spring Launch
2Retention Webinar
3Finance Retargeting
4Enterprise Search
Result set · 2 rows
campaign_idcampaign_namelead_idcreated_at
1Spring Launch3012024-01-21 09:10:00+00
1Spring Launch3022024-01-24 12:40:00+00

The preserved Spring Launch campaign matches two lead rows.

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

Practice this concept

Marketing wants every campaign in the result, including campaigns that have no lead rows, using RIGHT JOIN to preserve campaigns.

Available schema
marketing

Prefix tables with marketing.table_name.

campaign_idcampaign_namelead_idcreated_at
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