Learn SQL/Advanced/Subqueries/SQL Subquery vs JOIN

SQL Subquery vs JOIN

Choose a subquery or JOIN from the output grain and columns the question needs.

What & Why

A correlated EXISTS subquery answers an eligibility question without multiplying the outer rows, while a JOIN returns the matching child columns and therefore may produce several rows per parent.

The Queryflo examples intentionally have different grains: one row per eligible feature versus one row per positive feedback record. They demonstrate when each shape is appropriate, not interchangeable ways to return the same result.

See How It Works

BUSINESS QUESTION

Compare feature eligibility with the detailed positive-feedback rows behind it.

idnamedescriptionteamreleased_atdeprecated_at
1Activation ChecklistGuides new users through setupgrowth2024-01-20NULL
2CSV ExportExports report dataplatform2024-02-14NULL
3Invite NudgesPrompts workspace collaborationgrowth2024-03-05NULL
4Legacy DashboardOriginal reporting surfaceanalytics2023-08-102024-06-01
iduser_idfeature_idratingnps_scorecommentcreated_at
1101159Clear and useful2024-01-25 12:15:00+00
210224NULLExport worked well2024-02-20 15:40:00+00
3103147Helpful setup flow2024-03-18 09:05:00+00
410433NULLNeeds clearer timing2024-04-08 17:30:00+00
Choose the SQL shape that matches the required table grainStep 1 of 2
WHERE EXISTS (positive product.feedback row for feature)
feature_idfeaturepositive feedback exists
1Activation Checklistyes
2CSV Exportyes
3Invite Nudgesno
4Legacy Dashboardno

EXISTS returns one row per eligible feature and does not expose child detail.

EXAMPLE QUERY
-- One row per eligible feature
SELECT
  f.id AS feature_id,
  f.name
FROM product.features f
WHERE EXISTS (
  SELECT 1
  FROM product.feedback fb
  WHERE fb.feature_id = f.id
    AND fb.rating >= 4
)
ORDER BY f.id;

-- One row per positive feedback record
SELECT
  f.id AS feature_id,
  f.name,
  fb.rating,
  fb.created_at
FROM product.features f
JOIN product.feedback fb ON fb.feature_id = f.id
WHERE fb.rating >= 4
ORDER BY f.name, fb.created_at, fb.id;

This lesson's practice is part of Pro.

Advanced business practice

Sign up free to try it on a real business scenario