LIMIT, TOP and FETCH FIRST restrict the number of returned rows, using syntax that depends on the database system.
A report asking for the two largest sales has two requirements: ranking by amount and returning two records. A row limit handles only the second requirement. Without a suitable ORDER BY, the chosen records are not a dependable top-two result.
This reference adds detail to the main course. You can read it independently: the small database below supplies every table and row used in the examples. Start with the question each query answers, then compare the returned values with the data rather than memorising a line of syntax.
Set up the practice database
Run this setup once in a new practice database, before the examples. It uses four customers and six sales. Ana has two sales, Ben has one, Cara has two, and Dev has none.
Sale 106 has no customer link; sale 104 has an unknown amount. These deliberate test cases expose missing information and unmatched relationships.
CREATE TABLE customers (
id INTEGER PRIMARY KEY,
name VARCHAR(40) NOT NULL,
city VARCHAR(40),
manager_id INTEGER
);
CREATE TABLE sales (
id INTEGER PRIMARY KEY,
customer_id INTEGER,
amount DECIMAL(10,2),
status VARCHAR(20) NOT NULL,
created_on DATE NOT NULL
);
INSERT INTO customers (id,name,city,manager_id) VALUES
(1,'Ana','Leeds',NULL),(2,'Ben','Leeds',1),
(3,'Cara','Porto',1),(4,'Dev',NULL,2);
INSERT INTO sales (id,customer_id,amount,status,created_on) VALUES
(101,1,10,'paid','2026-01-01'),
(102,1,30,'pending','2026-01-02'),
(103,2,20,'paid','2026-01-02'),
(104,3,NULL,'pending','2026-02-01'),
(105,3,20,'paid','2026-02-02'),
(106,NULL,5,'paid','2026-02-03');An amount of zero would be a known value. The NULL amount here means the value is unknown. A customer with no matching sale differs from a sale whose customer_id is NULL.
The primary keys identify individual records even when amounts or cities repeat. Dates use year-month-day format. The examples specify sorting whenever order matters; insertion order alone does not guarantee display order.
How LIMIT, TOP and FETCH FIRST works
First define the order that makes first meaningful. ORDER BY amount DESC places larger known values ahead of smaller ones in engines whose descending NULL rule allows that, but default NULL positions vary. Filter unknown amounts when they should not compete in the ranking, or write an explicit missing-value sort key. Add id as a tie-breaker so equal amounts produce a predictable boundary. A limit of two is then a clear request for the first two rows in that total ordering.
LIMIT is commonly written after ORDER BY in PostgreSQL, MySQL and SQLite. TOP is placed immediately after SELECT in SQL Server, often as TOP (2). FETCH FIRST follows the ordering clause in PostgreSQL’s standard-style syntax. SQL Server uses OFFSET ... ROWS FETCH NEXT ... ROWS ONLY with ORDER BY for paged retrieval. The phrases look related, but copying the same statement into every engine is not a portability strategy.
OFFSET paging and keyset pagination
Offset pagination skips a specified number of ordered rows, then returns the requested number. It is easy to understand, but large offsets can require processing many discarded rows. Concurrent inserts or deletes can also move page boundaries. Keyset pagination uses a comparison with the last seen sort key instead. When ordering by amount and id, the continuation rule must use both values and the same direction; saving only amount loses the information needed to distinguish tied sales.
With ties means the boundary may return more than the nominal row count. SQL Server TOP ... WITH TIES and PostgreSQL FETCH ... WITH TIES keep rows tied on the ORDER BY values. If id is included as a unique tie-breaker, no two rows tie on the complete order. Choose whether the business question means exactly two records or every record sharing a top value. Limiting results also does not guarantee that the database scans only that many source rows; a sort or complex filter may still examine much more data.
MySQL, PostgreSQL, SQL Server and SQLite
The shown query runs in PostgreSQL, MySQL and SQLite. For SQL Server use SELECT TOP (2) id,amount FROM sales WHERE amount IS NOT NULL ORDER BY amount DESC,id ASC. PostgreSQL can use FETCH FIRST 2 ROWS ONLY. MySQL and SQLite do not use that FETCH FIRST form.
Check the engine-specific syntax and version requirements in SQL Server TOP, PostgreSQL row limits.
Practice task and worked solution
Return the smallest two known amounts. Break ties using the sale id. Use LIMIT for PostgreSQL, MySQL or SQLite.
Try the task before reading its worked solution. The supplied rows make the expected answer checkable by hand.
SELECT id,amount FROM sales
WHERE amount IS NOT NULL
ORDER BY amount ASC,id ASC LIMIT 2;id | amount
106 | 5
101 | 10The explicit ascending order places five before ten, so sales 106 and 101 form the first page. No tie occurs in this page, but the id ordering still defines how later tied values would be handled. Unknown amounts are excluded rather than left to a dialect default.
Order only by amount descending and inspect the tied twenties, then restore id as a tie-breaker. Change LIMIT 2 to LIMIT 3 and predict sale 105 as the additional record. In SQL Server translate the limit to TOP (3); in PostgreSQL compare FETCH FIRST 3 ROWS ONLY. Each version should express the same known-amount ordering rather than merely return the same row count.
SQL LIMIT, TOP and FETCH FIRST: Select the First Rows Syntax
LIMIT, TOP and FETCH FIRST
SELECT id,amount FROM sales
WHERE amount IS NOT NULL
ORDER BY amount DESC,id ASC
LIMIT 2;SQL LIMIT, TOP and FETCH FIRST: Select the First Rows Summary
LIMIT nin MySQL, PostgreSQL and SQLite,TOP (n)in SQL Server andFETCH FIRST n ROWS ONLYin standard SQL all cap the number of rows.- A row limit only means "first" or "top" after an
ORDER BYthat makes the order unique, for example with anidtie-breaker. - Decide explicitly how
NULLs should be treated, because their sort position differs between databases. OFFSETpaging is simple but slows down and shifts when rows change; keyset pagination continues from the last seen value.FETCH FIRST ... WITH TIEScan return more rows than requested when several rows tie at the boundary.
SQL LIMIT, TOP and FETCH FIRST: Select the First Rows Examples
Each example shows the code, the output it produces and what each part does.
The two largest known sales
The missing amount is excluded explicitly. Thirty ranks first. The two known twenties tie by amount, and the lower id places 103 before 105. LIMIT returns the first two records in this fully specified order.
SELECT id,amount FROM sales
WHERE amount IS NOT NULL
ORDER BY amount DESC,id ASC
LIMIT 2;id | amount
102 | 30
103 | 20Common SQL LIMIT, TOP and FETCH FIRST: Select the First Rows Mistakes
LIMIT without a complete ORDER BY
SELECT ... LIMIT 2 without ORDER BY returns two rows chosen by the execution plan, not necessarily the oldest, newest or largest. Ordering only by amount still leaves the choice between sales 103 and 105 uncertain at the boundary. Add the unique id when exactly two reproducible records are required.
SQL LIMIT, TOP and FETCH FIRST: Select the First Rows in Real Projects
Latest transactions on a dashboard
A sales dashboard may show the latest few transactions instead of loading every record. Use a stable date-and-id order, and retain the continuation values if the interface offers another page. If new records arrive during browsing, decide whether the user is seeing a fixed snapshot or a moving live list.
For a paged API, retain the last complete ordering key rather than only the display measure. A tied amount needs an id to establish continuation. Decide whether the product wants exactly n records or all records tied at the boundary; WITH TIES can legitimately exceed n and changes the pagination contract.
SQL LIMIT, TOP and FETCH FIRST: Select the First Rows FAQ
Does LIMIT sort the rows?
No. ORDER BY establishes the order; the limit only chooses how many rows from the front of it to return. Without ORDER BY, the database may return any rows, and the choice can change between runs.
Can WITH TIES exceed the requested count?
Yes. FETCH FIRST 2 ROWS WITH TIES includes every record tied at the boundary on the full ORDER BY expression, so amounts of 30, 20 and 20 all appear even though two were requested. It's supported by PostgreSQL, SQL Server (as TOP (2) WITH TIES) and Oracle, but not by MySQL or SQLite.
Is offset always suitable for large pages?
No. Deep offsets can be costly, because the database still reads and discards every skipped row, and unstable when rows are inserted or deleted while someone is paging. Consider keyset pagination, WHERE (amount, id) < (?, ?) with the last seen values, when the interface needs reliable continuation.
How do I get the second page of results?
Use LIMIT size OFFSET (page - 1) * size with a stable ORDER BY, such as ORDER BY created_on DESC, id DESC LIMIT 20 OFFSET 20 for page 2. SQL Server uses ORDER BY ... OFFSET 20 ROWS FETCH NEXT 20 ROWS ONLY, which requires an ORDER BY.
How do I get the top N rows for each group?
A single LIMIT applies to the whole result, not to each group. Number the rows within each group with ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY amount DESC) and keep rows numbered up to N, as the ranking functions lesson shows.
SQL LIMIT, TOP and FETCH FIRST: Select the First Rows Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Which two ids are selected by the largest-known-amount LIMIT example?
SQL LIMIT, TOP and FETCH FIRST: Select the First Rows Quiz
2 questions to check what you learned.
What makes a top-two result reproducible when amounts tie?
- Ordering only by amount while allowing tied rows to be chosen arbitrarily
- ORDER BY amount with a unique id tie-breaker
- Relying on the source insertion order
Which syntax is used immediately after SELECT in SQL Server?
- LIMIT n at the end of SELECT
- FETCH FIRST before the selected column list
- TOP (n)