Recipe 3.17. What to Do When LIMIT Requires the Wrong Sort Order


Recipe 3.17. What to Do When LIMIT Requires the "Wrong" Sort Order

Problem

LIMIT usually works best in conjunction with an ORDER BY clause that sorts rows. But sometimes the sort order is the opposite of what you want for the final result.

Solution

Use LIMIT in a subquery to retrieve the rows you want, and then use the outer query to sort them into the proper order.

Discussion

If you want the last four rows of a result set, you can obtain them easily by sorting the set in reverse order and using LIMIT 4. For example, the following statement returns the names and birth dates for the four people in the profile table who were born most recently:

mysql> SELECT name, birth FROM profile ORDER BY birth DESC LIMIT 4; +---------+------------+ | name    | birth      | +---------+------------+ | Shepard | 1975-09-02 | | Carl    | 1973-11-02 | | Fred    | 1970-04-13 | | Mort    | 1969-09-30 | +---------+------------+ 

But that requires sorting the birth values in descending order to place them at the head of the result set. What if you want the output rows to appear in ascending order instead? One way to solve this problem is to use two statements. First, use COUNT⁠(⁠ ⁠ ⁠) to find out how many rows are in the table:

mysql> SELECT COUNT(*) FROM profile; +----------+ | COUNT(*) | +----------+ |       10 | +----------+ 

Then, sort the values in ascending order and use the two-argument form of LIMIT to skip all but the last four rows:

mysql> SELECT name, birth FROM profile ORDER BY birth LIMIT 6, 4; +---------+------------+ | name    | birth      | +---------+------------+ | Mort    | 1969-09-30 | | Fred    | 1970-04-13 | | Carl    | 1973-11-02 | | Shepard | 1975-09-02 | +---------+------------+ 

That's somewhat unsatisfactory because it requires that you determine how many rows to skip. A more general approach is use LIMIT within a subquery to select the rows that you want, and then sort them in opposite order in the outer query:

mysql> SELECT * FROM     -> (SELECT name, birth FROM profile ORDER BY birth DESC LIMIT 4) AS t     -> ORDER BY birth; +---------+------------+ | name    | birth      | +---------+------------+ | Mort    | 1969-09-30 | | Fred    | 1970-04-13 | | Carl    | 1973-11-02 | | Shepard | 1975-09-02 | +---------+------------+ 

AS t is used here because any table referred to in the FROM clause must have a name.




MySQL Cookbook
MySQL Cookbook
ISBN: 059652708X
EAN: 2147483647
Year: 2004
Pages: 375
Authors: Paul DuBois

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net