Explain Codes LogoExplain Codes Logo

The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions

sql
pagination
offset-fetch
row-number
Anton ShumikhinbyAnton Shumikhin·Oct 26, 2024
TLDR

Here's your Jedi trick to sidestep the ORDER BY constraint in SQL constructs. Use a subquery to sort your data, following the usual SQL Server's processing rules:

SELECT * FROM ( --Who needs gatekeepers when you have subqueries! SELECT * FROM YourTable ORDER BY YourColumn ) AS SortedData

This workaround creates a derived table, SortedData, that SQL Server will happily play with, sidestepping the standard ORDER BY limitations.

Pagination using ORDER BY, OFFSET, and FETCH

For handling massive datasets, pagination becomes our best friend. SQL Server's OFFSET and FETCH clauses are uber helpful with ORDER BY. Here's your exemplar of pagination:

SELECT * FROM YourTable ORDER BY YourColumn OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;

With this pagination done right, the first 10 items are skipped, and the following 10 are fetched (like browsing page 2 of Google search results!)

Using ROW_NUMBER() for ordering hacks

When ORDER BY just doesn't play ball in subqueries and CTEs, summon ROW_NUMBER(). It assigns a unique sequential integer to each row within your result set. For instance:

SELECT ROW_NUMBER() OVER (ORDER BY YourColumn) AS Row, * FROM YourTable

The assigned row numbers can help you find your way around the data labyrinth.

Sneak peek: Advanced sorting for subqueries

Sometimes you want a subset of your data to march to a different drummer. In that case, combine ORDER BY with TOP or use it with FOR XML:

SELECT TOP 10 * FROM YourTable ORDER BY YourColumn

Here you have it! The perfect plan for targeted sorting within our cheeky little subquery.

Steering ORDER BY in functions

Do you have a table variable within your user-defined functions (UDFs)? Well, you're in luck. Populate it with data as you like and then use an ORDER BY when returning your results. Here’s a handy example:

CREATE FUNCTION MySortedData() RETURNS @MySortedTable TABLE ( MyColumn INT ) AS BEGIN -- Populate it and they will come...in order INSERT INTO @MySortedTable SELECT MyColumn FROM MyTable ORDER BY MyColumn RETURN END

Structuring complex queries

'Tis not uncommon to face a wall in complex queries involving multiple subqueries or UNIONs. But don't worry — CTEs have got your back! CTEs enable structuring your queries so that the final SELECT statement is where all the ordering takes place. This way, you can avoid the traffic jam caused by ORDER BY.

Ordering gotchas and workarounds

Here are some of the smart fixes for using ORDER BY better:

  • Nest subqueries: This gives an opportunity to order your data before they are processed further up in the query structure.
  • Use ROW_NUMBER() with ORDER BY: This combination is perfect for numbering rows in an order, all set to be screened or processed in the outer query.
  • OFFSET and FETCH NEXT to the rescue: When you need to serve a slice of your data, server-side pagination comes in handy.
  • Table variables in UDF: When UDFs come into play, table variables are heroes set to take advantage of ORDER BY when returning results.