Everybody in this country should learn to program a computer, because it teaches you how to think.
—Steve Jobs
The ORDER BY clause in detail
If a SELECT
query gives you a number of rows as a result, the
order in which they are displayed is unpredictable. The only way
to get a certain order is to use the ORDER BY
clause.
You can test the code examples in the table ‘course’ of the schema ‘ucllcatalogue’ (or in your own version of this table in your personal schema).
Sort by columns
By column name
The following query shows three columns for all courses that have less than 6 credits:
SELECT code, credits, name
FROM course
WHERE credits < 6;
As mentioned, you can't say anything in advance about the order in which
these rows are displayed. If you want the rows sorted so that the credits
are arranged from small to large, you can do so by using the column header
in the ORDER BY
clause:
SELECT code, credits, name
FROM course
WHERE credits < 6
ORDER BY credits ASC;
The addition ASC
(‘ascending’) may be omitted, because that is
the standard sorting.
Because it is so important, let's again go over the order in which this query is executed:
-
First the
FROM
: which table(s) should be loaded into working memory? -
Then
WHERE
: only the rows that meet this condition are kept, the rest are deleted. -
Then the
GROUP BY
, immediately followed byHAVING
. These two clauses are not present in this example. -
Only then comes the
SELECT
clause: which columns should be shown? -
Finally, the
ORDER BY
: in what order are the rows displayed?
This is the result of the query:

The courses with the smallest number of credits are at the top. Within the rows with the same value for the number of credits (e.g., 3), the order is still unpredictable. However, you can specify more than one column to sort on. Suppose you want to first sort by increasing number of credits and then (within rows with the same number of credits) alphabetically by name, you can do that as follows:
SELECT code, credits, name
FROM course
WHERE credits < 6
ORDER BY credits, name;
This is the result:

Note that the order is important: ORDER BY credits, name
returns
a different result than ORDER BY name, credits
!
By column sequence number
As so often in SQL, there is a shorter way to write things. Take the last query as an example:
SELECT code, credits, name
FROM course
WHERE credits < 6
ORDER BY credits, name;
A shorter alternative is writing the column numbers of the columns
from the
SELECT
instead of using the name:
SELECT code, credits, name
FROM course
WHERE credits < 6
ORDER BY 2, 3;
You then obviously need to know what the column numbers are in the SELECT
. A small disadvantage is that you have to change the column numbers
if you decide to add an extra column in the SELECT
clause, like
e.g. in this extended query:
SELECT code, coordinator, credits, name -- extra second column
FROM course
WHERE credits < 6
ORDER BY 3, 4; -- add 1 to all column numbers
Sorting ascending and descending
With ASC
you sort from small to large. This is also the default
value, so you can omit it. Sorting from large to small is done with DESC
. Especially if English is not your native language, it can be a
challenge to figure out the correct sorting order from the question you're
trying to answer. After all, in language many different ways of saying
roughly the same thing. A small overview with some possibilities:
-
ASC
: from small to large, ascending, alphabetic, chronological, incremental, increasing, ... -
DESC
: from major to minor, descending, antichronological, ...
Sort by expressions
You already know that you can add new columns yourself (see chapter SELECT). You can do the same in the ORDER BY clause as the following example shows:
SELECT code, coordinator, credits, name
FROM course
ORDER BY
CASE
WHEN credits <= 6 THEN 'normal'
ELSE 'special'
END;
You can compare it to adding a new column (put the CASE
in the
SELECT
to try it out) and then sort by this new column. This query
gives all courses of 6 or less credits the value ‘normal’ and all larger courses
the value ‘special’. On these two values the results are then sorted. Because
‘special’ comes later in alphabetical order than ‘normal’ all courses with
6 or less credits will be at the top of the list.
A second example: the last letter of the course code often has a special meaning. The next query allows sorting by this last letter (‘A’, ‘H’ etc):
SELECT code, coordinator, credits, name
FROM course
ORDER BY substring(code FROM 6); -- all letters from the 6th, so only the last letter
What about NULL values?
As already explained in
the solution of the first exercise on the CSV dataset the SQL standard does not define what to do with NULL
values
in a column being sorted. PostgreSQL considers NULL
as a value
greater than all other values, and so rows with this value will appear in the
column at the bottom of the list. There are other database systems that do
it the other way around ...
Exercises
List all courses sorted alphabetically by coordinator and for each coordinator sorted in ascending order by semester.
SELECT name, coordinator, semester
FROM course
ORDER BY coordinator ASC, semester ASC;
Sort the courses based on how long they have been given. The courses
that have been given the longest are at the top. If the end date is NULL
, you may set the number of years equal to 1.
SELECT name, start_date, end_date,
CASE
WHEN end_date IS NULL THEN 1
ELSE(end_date - start_date) / 365.25 -- Every 4 years a leap year, not entirely correct, but good enough
END AS number_of_years_given
FROM course
ORDER BY 4 DESC;
Exercises SQLzoo
Table of nobel prize winners
A table of noble prize winners with following columns:
- yr: year,
- subject: field of study, subject,
- winner: name of the winner.
Exercise Series 3 contains mainly exercises on WHERE
. In the last
exercises, you should also use ORDER BY
.
Now make quiz 3 on the table with the Nobel laureates.