MySQL
SQL queries
database management
data retrieval
last row selection

Select last row in MySQL

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In MySQL, there is no meaningful "last row" unless you define what last means. Tables are unordered sets of rows, so the correct query always depends on an explicit ordering column such as an auto-increment ID, timestamp, or some other business-specific sort key.

Define the Ordering Column First

Most of the time, people mean one of these:

  • the row with the highest primary key,
  • the most recently created row,
  • the row with the latest business timestamp.

Once that meaning is clear, the query becomes straightforward.

Use ORDER BY ... DESC LIMIT 1

If the table has an increasing ID and you want the row with the highest ID:

sql
1SELECT *
2FROM orders
3ORDER BY order_id DESC
4LIMIT 1;

If recency should follow a timestamp instead:

sql
1SELECT *
2FROM orders
3ORDER BY created_at DESC
4LIMIT 1;

This is the standard pattern. The critical part is choosing the column that actually represents the meaning of "last" in your application.

Avoid Assuming Insert Order Without a Sort

A query like this is wrong for the stated goal:

sql
SELECT * FROM orders LIMIT 1;

Without ORDER BY, MySQL is free to return rows in whatever order the optimizer finds convenient. It may look stable in testing, but it is not a contract you should rely on.

Use Tie-Breakers When Needed

If the ordering column is not unique, add a tie-breaker so the result is deterministic.

sql
1SELECT *
2FROM orders
3ORDER BY created_at DESC, order_id DESC
4LIMIT 1;

This matters when several rows can share the same timestamp or business priority value.

"Last Inserted Row" Is a Different Question

Sometimes developers really want the last row inserted by the current connection after an INSERT. In that case, LAST_INSERT_ID() is often the relevant tool, not a descending table scan.

sql
INSERT INTO orders(customer_id) VALUES (42);
SELECT LAST_INSERT_ID();

That gives the generated auto-increment value for the current session. It is not the same as querying the whole table for the highest row.

Performance Considerations

For large tables, make sure the ordering column is indexed. Sorting by an indexed primary key or timestamp is much cheaper than forcing MySQL to scan and sort an entire table unnecessarily.

The query pattern is simple, but the indexing strategy still matters.

Business Meaning Should Drive the Query

Many bugs around "last row" come from using the highest numeric ID when the application actually cares about the latest payment event, the most recent status change, or the newest timestamp from another table. The SQL pattern is simple, but the semantic choice of sort column should come from the business rule, not from convenience.

Common Pitfalls

  • Asking for the "last row" without defining what column determines lastness.
  • Using LIMIT 1 without ORDER BY and assuming the result is meaningful.
  • Ordering by a non-unique timestamp without a deterministic tie-breaker.
  • Confusing the highest row in the table with the last insert made by the current session.
  • Ignoring indexing on the chosen sort column in large tables.

Summary

  • MySQL tables do not have an inherent last row.
  • Use ORDER BY ... DESC LIMIT 1 on the column that defines recency or ordering for your use case.
  • Add tie-breakers when the main ordering column is not unique.
  • LAST_INSERT_ID() answers a different question about the current session’s insert.
  • Correct ordering matters more than memorizing one SQL snippet.

Course illustration
Course illustration

All Rights Reserved.