LEFT JOIN only first row
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
A plain LEFT JOIN returns all matching rows from the right table, which duplicates parent rows whenever multiple children exist. If you need only one child per parent, you must define what first means and encode that rule in SQL. The most reliable methods use deterministic ordering with window functions or database-specific alternatives.
Define First Row Explicitly
The phrase first row is ambiguous unless tied to a sort rule. Common definitions include earliest timestamp, highest priority, or smallest identifier.
A correct query should always answer these two questions:
- which column defines ordering
- how ties are broken consistently
Without this, output may vary by execution plan.
Portable Solution with ROW_NUMBER
Window functions are the most portable approach across modern SQL engines.
This preserves all parent rows and selects one deterministic child row when available.
SQL Server Pattern with OUTER APPLY
In SQL Server, OUTER APPLY plus TOP 1 can be concise and readable.
This style is convenient when first-row logic includes additional filtering or computed ranking.
PostgreSQL Pattern with DISTINCT ON
PostgreSQL has a compact option using DISTINCT ON.
This is elegant but less portable than the window-function approach.
Preserve LEFT JOIN Behavior
A common mistake is adding child filters in the outer WHERE clause, which can drop unmatched parents and effectively turn the query into inner-join behavior.
Prefer filtering in one of these places:
- inside the ranking CTE
- inside
OUTER APPLYsubquery - in the
ONclause
That keeps unmatched parent rows in the result set.
Indexing for Performance
Selecting one child per parent can be expensive on large child tables unless indexes match partition and order rules.
Useful index pattern:
- '
(parent_id, created_at, child_id)'
This helps the database find top-ranked child rows quickly. Validate with execution plans, not assumptions.
Deterministic Tie Handling
If several child rows share the same timestamp, include a stable tie-breaker such as child_id. Deterministic output is essential for reports, caching layers, and audit logic.
For critical data pipelines, add tests that lock expected row identity for representative parent groups.
Example Validation Query
You can verify one-row-per-parent behavior by checking duplicates in the result.
This query should return no rows.
Common Pitfalls
- Using
DISTINCTto hide duplicates without defining selection order. - Using
TOP 1orLIMIT 1withoutORDER BY. - Applying child filters in
WHEREand dropping unmatched parents. - Forgetting tie-break columns and getting non-deterministic results.
- Ignoring index design for parent-grouped selection queries.
Summary
- '
LEFT JOINalone does not select one child row per parent.' - Define first-row logic with explicit deterministic ordering.
- Use
ROW_NUMBERfor portability, or engine-specific shortcuts where appropriate. - Keep filters in ranking or join logic to preserve outer-join semantics.
- Add proper indexes and tie-breakers for stable, performant queries.
Related reading
- Let MySQL users create databases, but allow access to only their own databases
- Library not loaded libmysqlclient.16.dylib error when trying to run 'rails server' on OS X 10.6 with mysql2 gem
- Like Operator in Entity Framework?
- Limit on Number of Attributes in Table DynamoDB?
- Levenshtein Distance Algorithm better than Onm?
- Levenshtein Matrix using only a diagonal strip
- Limiting the number of records from mysqldump?
- LINQ contains and a Lambda query

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.