MySQL select one column DISTINCT, with corresponding other columns
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
A frequent SQL requirement is to get one row per unique value in one column while still returning related columns from the same row. DISTINCT alone usually cannot express which related row to keep. The correct solution depends on your rule for choosing the representative row, such as latest timestamp, max score, or min id.
Why Plain DISTINCT Is Not Enough
DISTINCT applies to the whole selected row, not just one column.
If a customer has many orders, this still returns many rows because (customer_id, order_id, created_at) tuples differ.
When you want one row per customer_id, you must define which order row wins.
MySQL 8 Solution with Window Functions
In MySQL 8, ROW_NUMBER is often the cleanest pattern.
This returns the latest order per customer. You can change the ORDER BY rule to match your business logic.
MySQL 5.7 Compatible Pattern with Join to Aggregate
Without window functions, use a subquery to choose the key per group and then join back.
Example using latest timestamp per customer:
If ties are possible on created_at, add another tie-breaker, such as max id.
Tie-break rules should be explicit so results are deterministic.
Using ANY_VALUE and Why to Be Careful
MySQL supports ANY_VALUE for non-aggregated columns in grouped queries.
This is valid but not deterministic for arbitrary columns. Use it only when any representative value is acceptable. For most business cases, deterministic selection is required, so prefer window functions or join-back patterns.
Example Dataset and Query Outcome
Suppose this table:
Insert sample rows:
With latest-per-customer logic, results should return order 2 for customer 10 and order 3 for customer 20.
Performance and Indexing
These queries can become expensive on large tables. Add indexes that align with grouping and ordering:
For window function approach, proper partition and order indexes reduce sorting overhead.
Always validate query plan with EXPLAIN.
Common Pitfalls
A common mistake is using DISTINCT customer_id, other_columns and assuming one row per customer. Distinct applies to the full selected tuple, so duplicates by customer remain.
Another issue is failing to define tie-break logic. If multiple rows share max timestamp, results can be nondeterministic or duplicated.
Developers also choose patterns unsupported by deployed MySQL version. Window functions require MySQL 8 or newer, so confirm server version before adopting that syntax.
Summary
DISTINCTalone does not pick a single related row per group.- Define explicit selection logic such as latest timestamp or highest id.
- Use
ROW_NUMBERin MySQL 8 for clear and deterministic queries. - Use aggregate plus join-back pattern for MySQL 5.7 compatibility.
- Add supporting indexes and verify execution plans for performance.
Related reading
- MySQL SELECT only not null values
- MySQL Select Query - Get only first 10 characters of a value
- MySQL SELECT statement for the length of the field is greater than 1
- MySQL select where column is not empty
- MySQL SELECT WHERE datetime matches day and not necessarily time
- MySQL selecting rows where a column is null
- MySQL selecting yesterday's date
- MySQL Server has gone away when importing large sql file

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.