SQL Server Pagination: OFFSET-FETCH and Multi-Column Sorting Explained

SQL Server Pagination: OFFSET-FETCH and Multi-Column Sorting Explained

Real apps rarely show every row at once. Here’s how to sort by more than one column, split results into pages the correct way, and why a well-meaning shortcut (paginating without ORDER BY) causes bugs that only show up in production under load.

Paging Through Results(skip, take, repeat — the right way)1. ORDER BYsort first — city, rating DESC2. OFFSETskip the rows already shown3. FETCH NEXTgrab just this page’s rowsthe trap: duplicate values split unpredictably across pagesPROBLEMNonna’s Table · 4.7Sakura Grill · 4.7→ page split is arbitraryFIXORDER BY rating DESC,restaurant_id ASCstable across every pageOFFSET-FETCH needs ORDER BY —T-SQL throws a syntax error withoutit. No accidental unsorted paging.

Multi-Column Sort

SELECT name, city, rating FROM dbo.Restaurant
ORDER BY city ASC, rating DESC;

City sorts alphabetically first; within each city, restaurants sort by rating, highest first. Each column can independently be ASC (default) or DESC — read it left to right as “sort by this, and within ties, sort by this next.”

-- Sorting by an expression, not just a raw column, works too:
SELECT name, rating, price_range FROM dbo.Restaurant
ORDER BY rating / price_range DESC; -- crude "value for money" ranking

You can also sort by column position (ORDER BY 3 DESC) — it works, but avoid it in real code; a column reordering elsewhere in the query silently changes what you sort by, with no warning.

OFFSET-FETCH: The Standard Way to Paginate

SELECT name, rating FROM dbo.Restaurant
ORDER BY rating DESC
OFFSET 0 ROWS FETCH NEXT 3 ROWS ONLY;    -- page 1 (rows 1-3)

SELECT name, rating FROM dbo.Restaurant
ORDER BY rating DESC
OFFSET 3 ROWS FETCH NEXT 3 ROWS ONLY;    -- page 2 (rows 4-6)

The general formula for “page N with a page size of S” is OFFSET (N-1) * S ROWS FETCH NEXT S ROWS ONLY — this is exactly the calculation a web application’s backend does every time you click “next page” on a paginated table.

Why ORDER BY Is Non-Negotiable Here

OFFSET 3 ROWS FETCH NEXT 3 ROWS ONLY; — no ORDER BY = undefined which rows ORDER BY rating DESC OFFSET 3 ROWS FETCH NEXT 3 ROWS ONLY; — predictable

Without a defined sort order, SQL Server makes no guarantee about row order — “skip 3, take 3” is meaningless if the underlying order can silently shift between calls. OFFSET-FETCH is actually a syntax extension of ORDER BY itself in T-SQL — you cannot write it without an ORDER BY clause at all; SQL Server will raise a syntax error, which is the engine protecting you from this exact bug.

A Subtler Pagination Bug: Ties

-- Two restaurants both rated 4.7 could land on either side of a page boundary
-- unpredictably, if rating is the ONLY sort column and duplicates exist.
SELECT name, rating FROM dbo.Restaurant
ORDER BY rating DESC
OFFSET 0 ROWS FETCH NEXT 2 ROWS ONLY;

-- Fix: add a tie-breaker column that's guaranteed unique, like the primary key
SELECT name, rating FROM dbo.Restaurant
ORDER BY rating DESC, restaurant_id ASC
OFFSET 0 ROWS FETCH NEXT 2 ROWS ONLY;
Practice tip: Any time you paginate on a column that might have duplicate values (a rating, a status, a category), add the primary key as a final tie-breaker in ORDER BY. Without it, the exact same row can appear on two different pages, or vanish between pages, as data changes underneath a multi-page scroll — a real bug that’s genuinely hard to reproduce without knowing to look for it.

Key Takeaways

  • List multiple ORDER BY columns to sort within a sort — first column is primary, rest break ties
  • OFFSET-FETCH is the standard SQL Server pagination pattern: skip N rows, take the next M — and T-SQL enforces that it can’t be used without ORDER BY
  • Add a unique tie-breaker column (usually the primary key) to ORDER BY whenever the sort column can have duplicate values, to keep pagination stable

Enjoyed this?

Subscribe to get every new SQL Server lesson as soon as it’s published, and share it with a developer who’d find it useful.

📡 Subscribe via RSS  | 
Share on X  | 
Share on LinkedIn  | 
Share on Facebook

Want the full structured course with quizzes, projects, and 10+ exercises per chapter? Check out SQL Server Fundamentals, coming soon on this site.