πŸŽ‰ 75% of content is free forever β€” Unlock Premium from $10/mo β†’
CW
Search courses…
πŸ’Ό Servicesℹ️ Aboutβœ‰οΈ ContactView Pricing Plansfrom $10

LIMIT and OFFSET

SQL FundamentalsDML🟒 Free Lesson

Advertisement

SQL Fundamentals

LIMIT and OFFSET

Control exactly how many rows your query returns β€” essential for pagination and top-N queries.

  • LIMIT β€” restrict the number of rows returned
  • OFFSET β€” skip rows before returning results
  • Pagination β€” implement page-by-page browsing

LIMIT and OFFSET are the building blocks of data pagination.

What are LIMIT and OFFSET?

DfLIMIT

Restricts the maximum number of rows returned by a query. Without LIMIT, all matching rows are returned.

DfOFFSET

Skips a specified number of rows before returning results. Always used with LIMIT or FETCH to control the result window.

Pagination: LIMIT 3 OFFSET 3Skip 3 rows, return next 3 rowsAll RowsRow 1: SkippedRow 2: SkippedRow 3: SkippedRow 4: ReturnedRow 5: ReturnedRow 6: ReturnedRow 7+Result: 3 rowsOFFSETLIMIT
-- Return only the first n rows
SELECT * FROM table LIMIT n;

-- Skip offset rows, then return limit rows
SELECT * FROM table LIMIT n OFFSET offset;
ComponentDescriptionExample
LIMITMaximum rows to returnLIMIT 10
OFFSETRows to skip firstOFFSET 20

LIMIT Example

-- Get top 3 highest salaries
SELECT first_name, last_name, salary
FROM employees
ORDER BY salary DESC
LIMIT 3;
first_namelast_namesalary
EveBrown91000
CarolWilliams85000
AliceJohnson75000

Always use ORDER BY with LIMIT. Without ordering, the rows LIMIT returns are unpredictable and may change between queries.

LIMIT with OFFSET

-- Skip first 3, return next 3
SELECT first_name, last_name, salary
FROM employees
ORDER BY salary DESC
LIMIT 3 OFFSET 3;
first_namelast_namesalary
BobSmith62000
DanWilson54000

OFFSET Visualization

PositionEmployeeAction
1Eve: 91000Skipped by OFFSET
2Carol: 85000Skipped by OFFSET
3Alice: 75000Skipped by OFFSET
4Bob: 62000Returned by LIMIT
5Dan: 54000Returned by LIMIT

Pagination Pattern

DfOffset-Based Pagination

The standard pagination formula: OFFSET = (page_number - 1) * page_size. This allows users to browse through large datasets one page at a time.

-- Page 1 (rows 1-10)
SELECT * FROM products ORDER BY id LIMIT 10 OFFSET 0;

-- Page 2 (rows 11-20)
SELECT * FROM products ORDER BY id LIMIT 10 OFFSET 10;

-- Page 3 (rows 21-30)
SELECT * FROM products ORDER BY id LIMIT 10 OFFSET 20;

-- Page N formula: OFFSET = (N-1) * page_size
SELECT * FROM products ORDER BY id LIMIT 10 OFFSET 40;  -- Page 5
PageFormulaOFFSETRows Returned
1(1-1) * 1001-10
2(2-1) * 101011-20
3(3-1) * 102021-30
10(10-1) * 109091-100

The LIMIT/OFFSET pattern works well for small page sizes andζ΅… pagination. For deep pages (high OFFSET values), consider keyset pagination for better performance.

Keyset Pagination

DfKeyset Pagination

An alternative to OFFSET pagination that uses a WHERE clause on the sort column. Instead of skipping rows, it starts from the last seen value, providing consistent performance regardless of page depth.

-- OFFSET pagination (slow for large offsets)
SELECT * FROM orders
ORDER BY id
LIMIT 10 OFFSET 100000;  -- Must scan 100,000 rows!

-- Keyset pagination (consistent performance)
SELECT * FROM orders
WHERE id > 100000  -- Use last seen ID
ORDER BY id
LIMIT 10;          -- Always fast!
MethodOFFSET 0OFFSET 10,000OFFSET 100,000
OFFSET paginationFastModerateSlow
Keyset paginationFastFastFast

Use keyset pagination when you need to paginate through large datasets or when users scroll deep into results. It requires a sortable, sequential column like an ID or timestamp.

Database Differences

DatabaseSyntax
MySQLLIMIT 10 OFFSET 20 or LIMIT 20, 10
PostgreSQLLIMIT 10 OFFSET 20
SQLiteLIMIT 10 OFFSET 20
SQL ServerOFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY
Oracle 12c+OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY
-- MySQL / PostgreSQL / SQLite
SELECT * FROM products LIMIT 10 OFFSET 20;

-- SQL Server
SELECT TOP 10 * FROM products;
SELECT * FROM products
ORDER BY id
OFFSET 20 ROWS
FETCH NEXT 10 ROWS ONLY;

-- Oracle 12c+
SELECT * FROM products
FETCH FIRST 10 ROWS ONLY;

SELECT * FROM products
OFFSET 20 ROWS
FETCH NEXT 10 ROWS ONLY;

LIMIT with Subqueries

-- Top 5 products by total sales
SELECT product_id, SUM(quantity) as total_sold
FROM order_items
GROUP BY product_id
ORDER BY total_sold DESC
LIMIT 5;

LIMIT with CTE

-- Get top 10 customers by order total
WITH customer_totals AS (
    SELECT
        customer_id,
        SUM(total) as total_spent
    FROM orders
    GROUP BY customer_id
)
SELECT
    c.name,
    ct.total_spent
FROM customer_totals ct
JOIN customers c ON ct.customer_id = c.id
ORDER BY ct.total_spent DESC
LIMIT 10;

LIMIT with Other Clauses

-- LIMIT with WHERE
SELECT * FROM products
WHERE price > 50
ORDER BY price DESC
LIMIT 5;

-- LIMIT with GROUP BY
SELECT city, COUNT(*) as customer_count
FROM customers
GROUP BY city
ORDER BY customer_count DESC
LIMIT 10;

-- LIMIT with HAVING
SELECT city, COUNT(*) as customer_count
FROM customers
GROUP BY city
HAVING COUNT(*) > 5
ORDER BY customer_count DESC
LIMIT 5;

Performance Considerations

OFFSET SizePerformanceAlternative
0 - 1,000FastUse OFFSET
1,000 - 10,000ModerateConsider keyset
10,000+SlowUse keyset pagination
-- 1. Add index on ORDER BY column
CREATE INDEX idx_orders_date ON orders(order_date);

-- 2. Use covering index
CREATE INDEX idx_orders_covering
ON orders(order_date, id, customer_id, total);

-- 3. Keyset pagination for large offsets
-- Instead of:
SELECT * FROM orders ORDER BY id LIMIT 10 OFFSET 100000;

-- Use:
SELECT * FROM orders WHERE id > 100000 ORDER BY id LIMIT 10;

Large OFFSET values are slow because the database must scan and discard all skipped rows. For deep pagination, switch to keyset pagination or use a cursor-based approach.

Common Mistakes

-- BAD: LIMIT without ORDER BY
SELECT * FROM products LIMIT 10;

-- GOOD: Add ORDER BY for predictable results
SELECT * FROM products ORDER BY id LIMIT 10;

-- BAD: Large OFFSET for deep pages
SELECT * FROM orders ORDER BY id LIMIT 10 OFFSET 100000;

-- GOOD: Use keyset pagination
SELECT * FROM orders WHERE id > 100000 ORDER BY id LIMIT 10;

-- BAD: Using LIMIT in UPDATE/DELETE (database specific)
UPDATE products SET price = price * 1.1 LIMIT 10;  -- MySQL only

-- GOOD: Use subquery for portability
UPDATE products SET price = price * 1.1
WHERE id IN (SELECT id FROM products ORDER BY id LIMIT 10);

Practice Exercises

Exercise 1: Find the 5 most expensive products from a products table.

SELECT * FROM products
ORDER BY price DESC
LIMIT 5;

Exercise 2: Get page 3 of customers (10 per page), ordered by last name.

SELECT * FROM customers
ORDER BY last_name ASC
LIMIT 10 OFFSET 20;

Exercise 3: Find the 10 most recent orders.

SELECT * FROM orders
ORDER BY order_date DESC
LIMIT 10;

Exercise 4: Get the second page of products (5 per page) in the 'Electronics' category.

SELECT * FROM products
WHERE category = 'Electronics'
ORDER BY name ASC
LIMIT 5 OFFSET 5;

Key Takeaways

  1. LIMIT restricts the number of rows returned β€” essential for top-N queries
  2. OFFSET skips rows before returning results β€” enables pagination
  3. Always use with ORDER BY β€” without it, results are unpredictable
  4. OFFSET pagination is slow for deep pages β€” use keyset pagination instead
  5. Syntax varies by database β€” check your system's documentation
⭐

Premium Content

LIMIT and OFFSET

Unlock this lesson and 900+ advanced tutorials with a Premium plan.

🎯End-to-end Projects
πŸ’ΌInterview Prep
πŸ“œCertificates
🀝Community Access

Already a member? Log in

Need Expert SQL Help?

Get personalized tutoring, project support, or professional consulting.

Advertisement