Sorting/ordering rows
Basics
Section titled “Basics”First, let’s setup the example table.
-- Create a table as an exampleCREATE TABLE SortOrder( ID INT IDENTITY PRIMARY KEY, [Text] VARCHAR(256))GO
-- Insert rows into the tableINSERT INTO SortOrder ([Text])SELECT ('Lorem ipsum dolor sit amet, consectetur adipiscing elit')UNION ALL SELECT ('Pellentesque eu dapibus libero')UNION ALL SELECT ('Vestibulum et consequat est, ut hendrerit ligula')UNION ALL SELECT ('Suspendisse sodales est congue lorem euismod, vel facilisis libero pulvinar')UNION ALL SELECT ('Suspendisse lacus est, aliquam at varius a, fermentum nec mi')UNION ALL SELECT ('Praesent tincidunt tortor est, nec consequat dolor malesuada quis')UNION ALL SELECT ('Quisque at tempus arcu')GORemember that when retrieving data, if you don’t specify a row ordering clause (ORDER BY) SQL server does not guarantee the sorting (order of the columns) at any time. Really, at any time. And there’s no point arguing about that, it has been shown literaly thousands of times and all over the internet.
No ORDER BY == no sorting. End of story.
-- It may seem the rows are sorted by identifiers,-- but there is really no way of knowing if it will always work.-- And if you leave it like this in production, Murphy gives you a 100% that it wont.SELECT * FROM SortOrderGOThere are two directions data can be ordered by:
- ascending (moving upwards), using ASC
- descending (moving downwards), using DESC
-- Ascending - upwardsSELECT * FROM SortOrder ORDER BY ID ASCGO
-- Ascending is defaultSELECT * FROM SortOrder ORDER BY IDGO
-- Descending - downwardsSELECT * FROM SortOrder ORDER BY ID DESCGOWhen ordering by the textual column ((n)char or (n)varchar), pay attention that the order respects the collation. For more information on collation look up for the topic.
Ordering and sorting of data can consume resources. This is where properly created indexes come handy. For more information on indexes look up for the topic.
There is a possibility to pseudo-randomize the order of rows in your resultset. Just force the ordering to appear nondeterministic.
SELECT * FROM SortOrder ORDER BY CHECKSUM(NEWID())GOOrdering can be remembered in a stored procedure, and that’s the way you should do it if it is the last step of manipulating the rowset before showing it to the end user.
CREATE PROCEDURE GetSortOrderAS SELECT * FROM SortOrder ORDER BY ID DESCGO
EXEC GetSortOrderGOThere is a limited (and hacky) support for ordering in the SQL Server views as well, but be encouraged NOT to use it.
/* This may or may not work, and it depends on the way your SQL Server and updates are installed */CREATE VIEW VwSortOrder1AS SELECT TOP 100 PERCENT * FROM SortOrder ORDER BY ID DESCGO
SELECT * FROM VwSortOrder1GO
-- This will work, but hey... should you really use it?CREATE VIEW VwSortOrder2AS SELECT TOP 99999999 * FROM SortOrder ORDER BY ID DESCGO
SELECT * FROM VwSortOrder2GOFor ordering you can either use column names, aliases or column numbers in your ORDER BY.
SELECT *FROM SortOrderORDER BY [Text]
-- New resultset column aliased as 'Msg', feel free to use it for orderingSELECT ID, [Text] + ' (' + CAST(ID AS nvarchar(10)) + ')' AS MsgFROM SortOrderORDER BY Msg
-- Can be handy if you know your tables, but really NOT GOOD for productionSELECT *FROM SortOrderORDER BY 2I advise against using the numbers in your code, except if you want to forget about it the moment after you execute it.
Order by Case
Section titled “Order by Case”If you want to sort your data numerically or alphabetically, you can simply use order by [column]. If you want to sort using a custom hierarchy, use a case statement.
Group-----TotalYoungMiddleAgeOldMaleFemaleUsing a basic order by:
Select * from MyTableOrder by Groupreturns an alphabetical sort, which isn’t always desirable:
Group-----FemaleMaleMiddleAgeOldTotalYoungAdding a ‘case’ statement, assigning ascending numerical values in the order you want your data sorted:
Select * from MyTableOrder by case Group when 'Total' then 10 when 'Male' then 20 when 'Female' then 30 when 'Young' then 40 when 'MiddleAge' then 50 when 'Old' then 60 endreturns data in the order specified:
Group-----TotalMaleFemaleYoungMiddleAgeOld