Logically, relational data should
always be considered an unordered list. The primary key's purpose is to
uniquely identify the row, not sort the table. SQL Server usually
returns the data in the order of the primary key (because that's
probably the clustered index), but there's no logical guarantee of that
order. The only correct way to sort the results is with an ORDER BY clause.
SQL can sort by multiple columns, and the sort columns don't have to be columns that are returned by the SELECT,
so there's a lot of flexibility in how you can specify the columns.
Using Management Studio's Query Designer, you can create the ORDER BY by selecting the sort order for the column, as shown in Figure 1.
Although there is not a limit on the number of columns that you can specify in the ORDER BY
clause of the select statement, an internal operation exists that
indirectly enforces a limit.
Specifying the ORDER BY Using Column Names
The best way to sort the result set is to completely spell out the ORDER BY columns:
USE AdventureWorks;
SELECT FirstName, LastName
FROM Person.Person
ORDER BY LastName, FirstName;
Result:
FirstName LastName
------------- --------------------
Syed Abbas
Catherine Abel
Kim Abercrombie
. . .
Note
ORDER BY and the order of columns in the select list are completely independent.
Specifying the ORDER BY Using Expressions
In the case of sorting by an expression, you can repeat the entire expression in the ORDER BY
clause. This does not cause a performance hit because the SQL Server
Query Optimizer is smart enough to avoid recomputing the expression:
SELECT
LastName + ‘, ‘ + FirstName AS FullName
FROM Person.Person
ORDER BY LastName + ‘, ‘ + FirstName;
Result:
FullName
----------------------
Abbas, Syed
Abel, Catherine
Abercrombie, Kim
. . .
Using an expression in the ORDER BY
clause can solve some headaches. For example, some database developers
store product titles in two columns: One column includes the full
title, and the duplicate column stores the title stripped of the
leading “The.” In terms of performance, such denormalization might be a
good idea, but using a case expression within the ORDER BY clause correctly sorts without duplicating the title.
The AdventureWorks sample database includes a list of Product Descriptions. If the Description includes a leading “This,” then the CASE expression removes it from the data and passes to the ORDER BY:
USE AdventureWorks;
SELECT Description, LEN(Description) AS TextLength
FROM Production.ProductDescription
WHERE
Description LIKE ‘Replacement%'
ORDER BY
CASE
WHEN LEFT(Description, 5) = ‘This ‘
THEN Stuff(Description, 1, 5, ‘')
ELSE
Description
END;
Result:
Description TextLength
--------------------------------- ----------
Replacement mountain wheel for entry-level rider. 49
Replacement mountain wheel for entry-level rider. 49
Replacement mountain wheel for the casual to serious rider. 59
Replacement mountain wheel for the casual to serious rider. 59
Replacement rear mountain wheel for entry-level rider. 54
Replacement rear mountain wheel for the casual to serious rider. 64
Replacement rear wheel for entry-level cyclist. 47
Replacement road front wheel for entry-level cyclist. 53
Replacement road rear wheel for entry-level cyclist. 52
. . .