Streamhub's analytics team is building a quarterly reporting template and needs a complete grid of every user across every reporting period — one row per user-period combination, regardless of whether any data appears for that pairing.
Write a query to return the user ID and period name for every possible combination.
Assumptions:
- The
userstable contains every account on the platform. - The
periodstable contains the calendar windows used to bucket metrics (Q1, Q2, etc.). - The output's row count is the product of the two tables' row counts (every user paired with every period).
Output:
- One row per user-period combination, with columns
user_idandperiod_name.
Schema · analytics 5 tables
Run previews · Check grades
Write a query, then run it to see results here.
Worked solution Try it yourself first
SELECT
u.id AS user_id,
p.name AS period_name
FROM
users u
CROSS JOIN periods p The shape
CROSS JOIN with no ON clause pairs every row in users with every row in periods, producing the complete user-by-period grid the template needs. Every user appears four times — once for each quarter — regardless of whether they had any activity in that quarter.
Clause by clause
FROM users u CROSS JOIN periods pis the join. There's noONclause becauseCROSS JOINdoesn't take one — the operation is unconditional pairing. Ifusershas 80 rows andperiodshas 4, the result has 320 rows, the product of the two table sizes.u.id AS user_idreads the account ID from the users side of each paired row. The table aliasudisambiguates the column, sinceperiodsalso has anid.p.name AS period_namepulls the quarter label (Q1,Q2,Q3,Q4) from the periods side.
Why this and not INNER JOIN
An INNER JOIN requires a match condition. There is no column connecting users to periods — a user doesn't belong to a quarter and a quarter doesn't belong to a user. The relationship the report needs is the absence of a relationship: every user, every quarter, no filtering.
You practiced a CROSS JOIN to build a complete grid of combinations. The recurring shape: when the question is "every X paired with every Y, regardless of whether they're related," CROSS JOIN is the join type with no ON clause — the result is the cartesian product of the two tables.