Retrieving the last record in each group - MySQL
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Retrieving the last record in each group is a common requirement when working with SQL databases. In MySQL, this can be challenging due to its syntax and functionalities. However, there are several methods to efficiently perform this task. This article will explore different approaches to retrieve the last record in each group, explain their mechanisms, and provide examples for better understanding.
Key Approaches
1. Using GROUP BY and MAX()
When the "last" record is determined by a value that represents the latest entry (such as a timestamp), you can leverage the MAX() function. The plan here is to group by the desired column(s) while selecting the maximum value from the other column.
Syntax
Example
Consider a transactions table with columns customer_id, transaction_date, and amount. To find the latest transaction date for each customer, you would write:
While this gives the latest transaction date per customer, it does not include other details from the transaction. For that, further steps are required.
2. Using Subqueries
A common way to fetch additional information (besides the group key and aggregate) is to use subqueries. We can store the result of the first query in a subquery and then join it back with the original table.
Syntax
Example
Refining the previous example to include the transaction amount:
3. Using Window Functions
With the advent of MySQL 8.0, we can use window functions such as ROW_NUMBER() to solve this task more elegantly.
Syntax
Example
Again, applying this to our transactions example:
Performance Considerations
- Indexes: Ensure that the columns used in the
ORDER BYclauses and joins are indexed for performance optimization. - Execution Plan: Use
EXPLAINto analyze and optimize any SQL query performance issues.
Additional Tips
- DISTINCT ON: In some SQL dialects like PostgreSQL, the
DISTINCT ONkeyword simplifies this task, but it isn't available in MySQL, reinforcing the importance of understanding these workarounds. - Handling Ties: If you want to handle ties (e.g., multiple records having the same "last" timestamp), consider using
RANK()orDENSE_RANK()instead ofROW_NUMBER().
Summary Table
| Approach | Pros | Cons |
GROUP BY and MAX() | Simple and intuitive | Limited to retrieving max value, not surrounding data |
| Subqueries | Can retrieve complete records | More complex, possible performance issues with large data sets |
| Window Functions | Clean and flexible | Requires MySQL 8.0 or above, learning curve |
Conclusion
MySQL offers several techniques to retrieve the last record in each group, each suitable for different scenarios and capabilities. As a developer or DBA, understanding the nuances and efficiencies of each method will greatly enhance your SQL querying skills and database performance management. Always consider the specific needs and limitations of your context when choosing the most appropriate method.
Related reading
- Return 0 if field is null in MySQL
- RHEL environments in YugaByte DB
- Riak on top of LevelDB
- Ridiculously slow writes to Amazon DynamoDB PHP API
- Right database for machine learning on 100 TB of data
- Rolling upgrades in YugaByte DB - is it possible?
- Room - Schema export directory is not provided to the annotation processor so we cannot export the schema
- Room - Schema export directory is not provided to the annotation processor so we cannot export the schema

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseSystem Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.