Learn SQL/Intermediate/Joins/SQL Joining Three or More Tables

SQL Joining Three or More Tables

The same pattern from Multiple JOINs, generalized — there's no hard limit on how many tables one query can chain together.

What & Why

Nothing about the previous lesson's technique changes when a fourth, fifth, or sixth table joins the chain — each new JOIN still connects to the combined result so far. Real reporting queries chaining 4-6 tables together are common; a dozen or more isn't unusual in large, well-normalized databases.

See How It Works

BUSINESS QUESTION

Marketing combines campaigns with both lead and email-send activity in one coverage report.

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
idcampaign_idsent_atrecipientsopensclicksunsubscribesbounces
20112024-01-20 15:00:00+001200540180924
20222024-02-15 16:30:00+0080042096512
20332024-03-18 13:00:00+0015006102251431
20442024-04-08 14:00:00+0000000
EXAMPLE QUERY
SELECT
  c.name,
  COUNT(DISTINCT l.id) AS lead_count,
  COUNT(DISTINCT e.id) AS send_count
FROM marketing.campaigns c
LEFT JOIN marketing.leads l ON l.campaign_id = c.id
LEFT JOIN marketing.email_sends e ON e.campaign_id = c.id
GROUP BY c.id, c.name
ORDER BY c.name;
RESULT — exact output from the displayed Queryflo rows
namelead_countsend_count
Enterprise Search01
Finance Retargeting11
Retention Webinar11
Spring Launch21

DISTINCT protects the independent lead and send counts from row multiplication.

Now You Try

Practice this concept

Marketing wants every campaign with independent lead and email-send counts.

Available schema
marketing

Prefix tables with marketing.table_name.

campaign_namelead_countsend_count
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