MySQL select one column DISTINCT, with corresponding other columns
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
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.

