The results from a
SELECT
are, by default, indeterminate in the order
they will appear. Fortunately, SQL provides some tools for imposing
discipline on this seemingly random list: ordering and grouping.
You can tell a database to order any results you see by a certain
column. For example, if you specify that a query should order the
results by last_name
, then the results will appear
alphabetized according to the last_name
value.
Ordering is handled by the ORDER
BY
clause:
SELECT last_name, first_name, age FROM people ORDER BY last_name, first_name
In this situation, we are ordering by two
columns. You can order by any number of
columns. You can also use the special
ORDER
BY
RAND(
)
clause to return results in a random order.
If you want to see things in reverse order, add the
DESC
(descending) keyword:
ORDER BY last_name DESC
The DESC
keyword applies only to the field that
comes directly before it. If you are sorting on multiple fields, only
the field directly before DESC
is reversed; the
others are sorted in ascending order.
Sorting is actually a complex problem for applications that need to run on computers all over the world. The rules for sorting strings vary from alphabet to alphabet, even when two alphabets use mostly the same symbols. MySQL handles the problem of sorting by making it dependent on the character set used by the MySQL engine. Out of the box, the default character set is ISO-8859-1 (Latin-1). MySQL uses the sorting rules for Swedish and Finnish with ISO-8859-1.
To change the sorting rules, you change the character set. First, you need to make sure the correct character set was compiled into the server when you compiled and installed MySQL. With the proper character set compiled into the server, you can change the default character set by launching the server with the argument --default-character-set=CHARSET .
Because of the simplicity of the English alphabet, the use of a single set of sorting rules MySQL associates with ISO-8859-1 does not affect English sorting. This is not true, however, for languages such as Swedish and German, which both use the ISO-8859-1 character set. Swedish sorts ä after z, while German sorts ä before a. The default rules therefore fail German users.
MySQL lets you address this problem by creating custom character sets. When you compile the driver, you can compile in support for whatever character sets you desire as long as you have a configuration file for that character set. This file contains the characters that make up the character set and the rules for sorting them. You can write your own or use the ones that come with MySQL.
The real problem here is that MySQL incorrectly associates sorting rules with character sets. A character set is nothing more than a grouping of characters with a related purpose. Nothing about the ISO-8859-1 character set implies sorting for Swedes, Italians, Germans, or anyone else. When working with MySQL, however, you need to remember that sorting rules are directly tied to the character set.
Grouping lets you group rows with matching values for a specific column into a single row in order to operate on them together. You usually do this to perform aggregate functions on the results. We will go into functions a little later in the chapter.
Consider the following:
mysql> SELECT name, rank, salary FROM people;
+--------------+----------+--------+
| name | rank | salary |
+--------------+----------+--------+
| Jack Smith | Private | 23000 |
| Jane Walker | General | 125000 |
| June Sanders | Private | 22000 |
| John Barker | Sergeant | 45000 |
| Jim Castle | Sergeant | 38000 |
+--------------+----------+--------+
5 rows in set (0.01 sec)
If you want to get a list of different ranks, you can use the
GROUP BY
clause to get a full account of the
ranks:
mysql> SELECT rank FROM people GROUP BY rank;
+----------+
| rank |
+----------+
| General |
| Private |
| Sergeant |
+----------+
3 rows in set (0.01 sec)
You should not, however, think of these results as simply a listing
of the different ranks. The GROUP BY
clause
actually groups all of the rows matching the WHERE
clause (in this case, every row) based on the GROUP
BY
clause. The two privates are thus grouped together into
a single row with the rank Private
. The two
sergeants are similarly aggregated. With the individuals grouped
according to rank, you can find out the average salary for each rank.
Again, we will further discuss the functions you see in this example
later in the chapter.
mysql> SELECT rank, AVG(salary) FROM people GROUP BY rank;
+----------+-------------+
| rank | AVG(salary) |
+----------+-------------+
| General | 125000.0000 |
| Private | 22500.0000 |
| Sergeant | 41500.0000 |
+----------+-------------+
3 rows in set (0.04 sec)
Here you see the true power of grouping. This query uses an aggregate
function, AVG( )
, to operate on all of the rows
grouped together for each row. In this case, the salaries of the two
privates (23000
and 22000
) are
grouped together in the same row, and the AVG( )
function is applied to them.
The power of ordering and grouping combined with the utility of SQL functions enables you to do a great deal of data manipulation even before you retrieve the data from the server. However, you should take great care not to rely too heavily on this power. While it may seem more efficient to place as much processing load as possible onto the database server, this is not really the case. Your client application is dedicated to the needs of a particular client, while the server is shared by many clients. Because of the greater amount of work a server already has to do, it is almost always more efficient to place as little load as possible on the database server. MySQL may be the fastest database around, but you do not want to waste that speed on processing that can be handled by client applications.