The ORDER BY clause allows users to sort a result set prior to it being returned. It is perhaps the most straightforward clause among the BIG SIX because of users’ experiences using the popular spreadsheet software, Microsoft Excel. Like the sorting functionality afforded to users of Microsoft Excel, the ORDER BY clause permits users to sort result sets in ascending or descending order based on the values of one or more user-specified attributes. To illustrate the use of the ORDER BY clause, I will walk through a few examples. Following a few examples highlighting the clause’s basic usage, I’ll showcase a couple of additional examples aiming to explore the possible things a result set can be sorted by. Additionally, I will introduce a method to implement custom sorting and highlight how missing values are handled.
Before reading further, consider reviewing the Example Data section below to familiarize yourself with the data being used throughout the examples on this page. If you are already familiar with the data, then skip to the Basic Usage section.
Example Data
The schemas, corresponding tables, and data used in the example problems can be found at livesql.oracle.com. To more easily follow the examples covered on this page, consider first reading the table descriptions below and reviewing each table’s contents. To review the data maintained in each table, click on the icon next to the table name. To hide the data, click the icon again.
hr.employees
Contains information related to each employee and a hierarchal employee-manager relationship. There is one row per employee.
| employee_id | first_name | last_name | phone_number | hire_date | job_id | salary | commission_pct | manager_id | department_id | |
|---|---|---|---|---|---|---|---|---|---|---|
| 100 | Steven | King | SKING | 515.123.4567 | 17-Jun-03 | AD_PRES | 24000 | – | – | 90 |
| 101 | Neena | Kochhar | NKOCHHAR | 515.123.4568 | 21-Sep-05 | AD_VP | 17000 | – | 100 | 90 |
| 102 | Lex | De Haan | LDEHAAN | 515.123.4569 | 13-Jan-01 | AD_VP | 17000 | – | 100 | 90 |
| 103 | Alexander | Hunold | AHUNOLD | 590.423.4567 | 3-Jan-06 | IT_PROG | 9000 | – | 102 | 60 |
| 104 | Bruce | Ernst | BERNST | 590.423.4568 | 21-May-07 | IT_PROG | 6000 | – | 103 | 60 |
| 105 | David | Austin | DAUSTIN | 590.423.4569 | 25-Jun-05 | IT_PROG | 4800 | – | 103 | 60 |
| 106 | Valli | Pataballa | VPATABAL | 590.423.4560 | 5-Feb-06 | IT_PROG | 4800 | – | 103 | 60 |
| 107 | Diana | Lorentz | DLORENTZ | 590.423.5567 | 7-Feb-07 | IT_PROG | 4200 | – | 103 | 60 |
| 108 | Nancy | Greenberg | NGREENBE | 515.124.4569 | 17-Aug-02 | FI_MGR | 12008 | – | 101 | 100 |
| 109 | Daniel | Faviet | DFAVIET | 515.124.4169 | 16-Aug-02 | FI_ACCOUNT | 9000 | – | 108 | 100 |
| 110 | John | Chen | JCHEN | 515.124.4269 | 28-Sep-05 | FI_ACCOUNT | 8200 | – | 108 | 100 |
| 111 | Ismael | Sciarra | ISCIARRA | 515.124.4369 | 30-Sep-05 | FI_ACCOUNT | 7700 | – | 108 | 100 |
| 112 | Jose Manuel | Urman | JMURMAN | 515.124.4469 | 7-Mar-06 | FI_ACCOUNT | 7800 | – | 108 | 100 |
| 113 | Luis | Popp | LPOPP | 515.124.4567 | 7-Dec-07 | FI_ACCOUNT | 6900 | – | 108 | 100 |
| 114 | Den | Raphaely | DRAPHEAL | 515.127.4561 | 7-Dec-02 | PU_MAN | 11000 | – | 100 | 30 |
| 115 | Alexander | Khoo | AKHOO | 515.127.4562 | 18-May-03 | PU_CLERK | 3100 | – | 114 | 30 |
| 116 | Shelli | Baida | SBAIDA | 515.127.4563 | 24-Dec-05 | PU_CLERK | 2900 | – | 114 | 30 |
| 117 | Sigal | Tobias | STOBIAS | 515.127.4564 | 24-Jul-05 | PU_CLERK | 2800 | – | 114 | 30 |
| 118 | Guy | Himuro | GHIMURO | 515.127.4565 | 15-Nov-06 | PU_CLERK | 2600 | – | 114 | 30 |
| 119 | Karen | Colmenares | KCOLMENA | 515.127.4566 | 10-Aug-07 | PU_CLERK | 2500 | – | 114 | 30 |
| 120 | Matthew | Weiss | MWEISS | 650.123.1234 | 18-Jul-04 | ST_MAN | 8000 | – | 100 | 50 |
| 121 | Adam | Fripp | AFRIPP | 650.123.2234 | 10-Apr-05 | ST_MAN | 8200 | – | 100 | 50 |
| 122 | Payam | Kaufling | PKAUFLIN | 650.123.3234 | 1-May-03 | ST_MAN | 7900 | – | 100 | 50 |
| 123 | Shanta | Vollman | SVOLLMAN | 650.123.4234 | 10-Oct-05 | ST_MAN | 6500 | – | 100 | 50 |
| 124 | Kevin | Mourgos | KMOURGOS | 650.123.5234 | 16-Nov-07 | ST_MAN | 5800 | – | 100 | 50 |
| 125 | Julia | Nayer | JNAYER | 650.124.1214 | 16-Jul-05 | ST_CLERK | 3200 | – | 120 | 50 |
| 126 | Irene | Mikkilineni | IMIKKILI | 650.124.1224 | 28-Sep-06 | ST_CLERK | 2700 | – | 120 | 50 |
| 127 | James | Landry | JLANDRY | 650.124.1334 | 14-Jan-07 | ST_CLERK | 2400 | – | 120 | 50 |
| 128 | Steven | Markle | SMARKLE | 650.124.1434 | 8-Mar-08 | ST_CLERK | 2200 | – | 120 | 50 |
| 129 | Laura | Bissot | LBISSOT | 650.124.5234 | 20-Aug-05 | ST_CLERK | 3300 | – | 121 | 50 |
| 130 | Mozhe | Atkinson | MATKINSO | 650.124.6234 | 30-Oct-05 | ST_CLERK | 2800 | – | 121 | 50 |
| 131 | James | Marlow | JAMRLOW | 650.124.7234 | 16-Feb-05 | ST_CLERK | 2500 | – | 121 | 50 |
| 132 | TJ | Olson | TJOLSON | 650.124.8234 | 10-Apr-07 | ST_CLERK | 2100 | – | 121 | 50 |
| 133 | Jason | Mallin | JMALLIN | 650.127.1934 | 14-Jun-04 | ST_CLERK | 3300 | – | 122 | 50 |
| 134 | Michael | Rogers | MROGERS | 650.127.1834 | 26-Aug-06 | ST_CLERK | 2900 | – | 122 | 50 |
| 135 | Ki | Gee | KGEE | 650.127.1734 | 12-Dec-07 | ST_CLERK | 2400 | – | 122 | 50 |
| 136 | Hazel | Philtanker | HPHILTAN | 650.127.1634 | 6-Feb-08 | ST_CLERK | 2200 | – | 122 | 50 |
| 137 | Renske | Ladwig | RLADWIG | 650.121.1234 | 14-Jul-03 | ST_CLERK | 3600 | – | 123 | 50 |
| 138 | Stephen | Stiles | SSTILES | 650.121.2034 | 26-Oct-05 | ST_CLERK | 3200 | – | 123 | 50 |
| 139 | John | Seo | JSEO | 650.121.2019 | 12-Feb-06 | ST_CLERK | 2700 | – | 123 | 50 |
| 140 | Joshua | Patel | JPATEL | 650.121.1834 | 6-Apr-06 | ST_CLERK | 2500 | – | 123 | 50 |
| 141 | Trenna | Rajs | TRAJS | 650.121.8009 | 17-Oct-03 | ST_CLERK | 3500 | – | 124 | 50 |
| 142 | Curtis | Davies | CDAVIES | 650.121.2994 | 29-Jan-05 | ST_CLERK | 3100 | – | 124 | 50 |
| 143 | Randall | Matos | RMATOS | 650.121.2874 | 15-Mar-06 | ST_CLERK | 2600 | – | 124 | 50 |
| 144 | Peter | Vargas | PVARGAS | 650.121.2004 | 9-Jul-06 | ST_CLERK | 2500 | – | 124 | 50 |
| 145 | John | Russell | JRUSSEL | 011.44.1344.429268 | 1-Oct-04 | SA_MAN | 14000 | 0.4 | 100 | 80 |
| 146 | Karen | Partners | KPARTNER | 011.44.1344.467268 | 5-Jan-05 | SA_MAN | 13500 | 0.3 | 100 | 80 |
| 147 | Alberto | Errazuriz | AERRAZUR | 011.44.1344.429278 | 10-Mar-05 | SA_MAN | 12000 | 0.3 | 100 | 80 |
| 148 | Gerald | Cambrault | GCAMBRAU | 011.44.1344.619268 | 15-Oct-07 | SA_MAN | 11000 | 0.3 | 100 | 80 |
| 149 | Eleni | Zlotkey | EZLOTKEY | 011.44.1344.429018 | 29-Jan-08 | SA_MAN | 10500 | 0.2 | 100 | 80 |
| 150 | Peter | Tucker | PTUCKER | 011.44.1344.129268 | 30-Jan-05 | SA_REP | 10000 | 0.3 | 145 | 80 |
| 151 | David | Bernstein | DBERNSTE | 011.44.1344.345268 | 24-Mar-05 | SA_REP | 9500 | 0.25 | 145 | 80 |
| 152 | Peter | Hall | PHALL | 011.44.1344.478968 | 20-Aug-05 | SA_REP | 9000 | 0.25 | 145 | 80 |
| 153 | Christopher | Olsen | COLSEN | 011.44.1344.498718 | 30-Mar-06 | SA_REP | 8000 | 0.2 | 145 | 80 |
| 154 | Nanette | Cambrault | NCAMBRAU | 011.44.1344.987668 | 9-Dec-06 | SA_REP | 7500 | 0.2 | 145 | 80 |
| 155 | Oliver | Tuvault | OTUVAULT | 011.44.1344.486508 | 23-Nov-07 | SA_REP | 7000 | 0.15 | 145 | 80 |
| 156 | Janette | King | JKING | 011.44.1345.429268 | 30-Jan-04 | SA_REP | 10000 | 0.35 | 146 | 80 |
| 157 | Patrick | Sully | PSULLY | 011.44.1345.929268 | 4-Mar-04 | SA_REP | 9500 | 0.35 | 146 | 80 |
| 158 | Allan | McEwen | AMCEWEN | 011.44.1345.829268 | 1-Aug-04 | SA_REP | 9000 | 0.35 | 146 | 80 |
| 159 | Lindsey | Smith | LSMITH | 011.44.1345.729268 | 10-Mar-05 | SA_REP | 8000 | 0.3 | 146 | 80 |
| 160 | Louise | Doran | LDORAN | 011.44.1345.629268 | 15-Dec-05 | SA_REP | 7500 | 0.3 | 146 | 80 |
| 161 | Sarath | Sewall | SSEWALL | 011.44.1345.529268 | 3-Nov-06 | SA_REP | 7000 | 0.25 | 146 | 80 |
| 162 | Clara | Vishney | CVISHNEY | 011.44.1346.129268 | 11-Nov-05 | SA_REP | 10500 | 0.25 | 147 | 80 |
| 163 | Danielle | Greene | DGREENE | 011.44.1346.229268 | 19-Mar-07 | SA_REP | 9500 | 0.15 | 147 | 80 |
| 164 | Mattea | Marvins | MMARVINS | 011.44.1346.329268 | 24-Jan-08 | SA_REP | 7200 | 0.1 | 147 | 80 |
| 165 | David | Lee | DLEE | 011.44.1346.529268 | 23-Feb-08 | SA_REP | 6800 | 0.1 | 147 | 80 |
| 166 | Sundar | Ande | SANDE | 011.44.1346.629268 | 24-Mar-08 | SA_REP | 6400 | 0.1 | 147 | 80 |
| 167 | Amit | Banda | ABANDA | 011.44.1346.729268 | 21-Apr-08 | SA_REP | 6200 | 0.1 | 147 | 80 |
| 168 | Lisa | Ozer | LOZER | 011.44.1343.929268 | 11-Mar-05 | SA_REP | 11500 | 0.25 | 148 | 80 |
| 169 | Harrison | Bloom | HBLOOM | 011.44.1343.829268 | 23-Mar-06 | SA_REP | 10000 | 0.2 | 148 | 80 |
| 170 | Tayler | Fox | TFOX | 011.44.1343.729268 | 24-Jan-06 | SA_REP | 9600 | 0.2 | 148 | 80 |
| 171 | William | Smith | WSMITH | 011.44.1343.629268 | 23-Feb-07 | SA_REP | 7400 | 0.15 | 148 | 80 |
| 172 | Elizabeth | Bates | EBATES | 011.44.1343.529268 | 24-Mar-07 | SA_REP | 7300 | 0.15 | 148 | 80 |
| 173 | Sundita | Kumar | SKUMAR | 011.44.1343.329268 | 21-Apr-08 | SA_REP | 6100 | 0.1 | 148 | 80 |
| 174 | Ellen | Abel | EABEL | 011.44.1644.429267 | 11-May-04 | SA_REP | 11000 | 0.3 | 149 | 80 |
| 175 | Alyssa | Hutton | AHUTTON | 011.44.1644.429266 | 19-Mar-05 | SA_REP | 8800 | 0.25 | 149 | 80 |
| 176 | Jonathon | Taylor | JTAYLOR | 011.44.1644.429265 | 24-Mar-06 | SA_REP | 8600 | 0.2 | 149 | 80 |
| 177 | Jack | Livingston | JLIVINGS | 011.44.1644.429264 | 23-Apr-06 | SA_REP | 8400 | 0.2 | 149 | 80 |
| 178 | Kimberely | Grant | KGRANT | 011.44.1644.429263 | 24-May-07 | SA_REP | 7000 | 0.15 | 149 | – |
| 179 | Charles | Johnson | CJOHNSON | 011.44.1644.429262 | 4-Jan-08 | SA_REP | 6200 | 0.1 | 149 | 80 |
| 180 | Winston | Taylor | WTAYLOR | 650.507.9876 | 24-Jan-06 | SH_CLERK | 3200 | – | 120 | 50 |
| 181 | Jean | Fleaur | JFLEAUR | 650.507.9877 | 23-Feb-06 | SH_CLERK | 3100 | – | 120 | 50 |
| 182 | Martha | Sullivan | MSULLIVA | 650.507.9878 | 21-Jun-07 | SH_CLERK | 2500 | – | 120 | 50 |
| 183 | Girard | Geoni | GGEONI | 650.507.9879 | 3-Feb-08 | SH_CLERK | 2800 | – | 120 | 50 |
| 184 | Nandita | Sarchand | NSARCHAN | 650.509.1876 | 27-Jan-04 | SH_CLERK | 4200 | – | 121 | 50 |
| 185 | Alexis | Bull | ABULL | 650.509.2876 | 20-Feb-05 | SH_CLERK | 4100 | – | 121 | 50 |
| 186 | Julia | Dellinger | JDELLING | 650.509.3876 | 24-Jun-06 | SH_CLERK | 3400 | – | 121 | 50 |
| 187 | Anthony | Cabrio | ACABRIO | 650.509.4876 | 7-Feb-07 | SH_CLERK | 3000 | – | 121 | 50 |
| 188 | Kelly | Chung | KCHUNG | 650.505.1876 | 14-Jun-05 | SH_CLERK | 3800 | – | 122 | 50 |
| 189 | Jennifer | Dilly | JDILLY | 650.505.2876 | 13-Aug-05 | SH_CLERK | 3600 | – | 122 | 50 |
| 190 | Timothy | Gates | TGATES | 650.505.3876 | 11-Jul-06 | SH_CLERK | 2900 | – | 122 | 50 |
| 191 | Randall | Perkins | RPERKINS | 650.505.4876 | 19-Dec-07 | SH_CLERK | 2500 | – | 122 | 50 |
| 192 | Sarah | Bell | SBELL | 650.501.1876 | 4-Feb-04 | SH_CLERK | 4000 | – | 123 | 50 |
| 193 | Britney | Everett | BEVERETT | 650.501.2876 | 3-Mar-05 | SH_CLERK | 3900 | – | 123 | 50 |
| 194 | Samuel | McCain | SMCCAIN | 650.501.3876 | 1-Jul-06 | SH_CLERK | 3200 | – | 123 | 50 |
| 195 | Vance | Jones | VJONES | 650.501.4876 | 17-Mar-07 | SH_CLERK | 2800 | – | 123 | 50 |
| 196 | Alana | Walsh | AWALSH | 650.507.9811 | 24-Apr-06 | SH_CLERK | 3100 | – | 124 | 50 |
| 197 | Kevin | Feeney | KFEENEY | 650.507.9822 | 23-May-06 | SH_CLERK | 3000 | – | 124 | 50 |
| 198 | Donald | OConnell | DOCONNEL | 650.507.9833 | 21-Jun-07 | SH_CLERK | 2600 | – | 124 | 50 |
| 199 | Douglas | Grant | DGRANT | 650.507.9844 | 13-Jan-08 | SH_CLERK | 2600 | – | 124 | 50 |
| 200 | Jennifer | Whalen | JWHALEN | 515.123.4444 | 17-Sep-03 | AD_ASST | 4400 | – | 101 | 10 |
| 201 | Michael | Hartstein | MHARTSTE | 515.123.5555 | 17-Feb-04 | MK_MAN | 13000 | – | 100 | 20 |
| 202 | Pat | Fay | PFAY | 603.123.6666 | 17-Aug-05 | MK_REP | 6000 | – | 201 | 20 |
| 203 | Susan | Mavris | SMAVRIS | 515.123.7777 | 7-Jun-02 | HR_REP | 6500 | – | 101 | 40 |
| 204 | Hermann | Baer | HBAER | 515.123.8888 | 7-Jun-02 | PR_REP | 10000 | – | 101 | 70 |
| 205 | Shelley | Higgins | SHIGGINS | 515.123.8080 | 7-Jun-02 | AC_MGR | 12008 | – | 101 | 110 |
| 206 | William | Gietz | WGIETZ | 515.123.8181 | 7-Jun-02 | AC_ACCOUNT | 8300 | – | 205 | 110 |
oe.orders
For each order placed by a customer, various attributes are captured. There is one row per order.
| order_id | order_date | order_mode | customer_id | order_status | order_total | sales_rep_id | promotion_id |
|---|---|---|---|---|---|---|---|
| 2458 | 16-AUG-07 03.34.12.234359 PM | direct | 101 | 0 | 78279.6 | 153 | – |
| 2397 | 19-NOV-07 02.41.54.696211 PM | direct | 102 | 1 | 42283.2 | 154 | – |
| 2454 | 02-OCT-07 05.49.34.678340 PM | direct | 103 | 1 | 6653.4 | 154 | – |
| 2354 | 14-JUL-08 06.18.23.234567 PM | direct | 104 | 0 | 46257 | 155 | – |
| 2358 | 08-JAN-08 05.03.12.654278 PM | direct | 105 | 2 | 7826 | 155 | – |
| 2381 | 14-MAY-08 08.59.08.843679 PM | direct | 106 | 3 | 23034.6 | 156 | – |
| 2440 | 31-AUG-07 09.53.06.008765 PM | direct | 107 | 3 | 70576.9 | 156 | – |
| 2357 | 08-JAN-06 08.19.44.123456 PM | direct | 108 | 5 | 59872.4 | 158 | – |
| 2394 | 10-FEB-08 09.22.35.564789 PM | direct | 109 | 5 | 21863 | 158 | – |
| 2435 | 02-SEP-07 11.22.53.134567 PM | direct | 144 | 6 | 62303 | 159 | – |
| 2455 | 20-SEP-07 11.34.11.456789 AM | direct | 145 | 7 | 14087.5 | 160 | – |
| 2379 | 16-MAY-07 02.22.24.234567 AM | direct | 146 | 8 | 17848.2 | 161 | – |
| 2396 | 02-FEB-06 01.34.56.345678 AM | direct | 147 | 8 | 34930 | 161 | – |
| 2406 | 29-JUN-07 04.41.20.098765 AM | direct | 148 | 8 | 2854.2 | 161 | – |
| 2434 | 13-SEP-07 05.49.30.647893 AM | direct | 149 | 8 | 268651.8 | 161 | – |
| 2436 | 02-SEP-07 06.18.04.378034 AM | direct | 116 | 8 | 6394.8 | 161 | – |
| 2446 | 27-JUL-07 07.03.08.302945 AM | direct | 117 | 8 | 103679.3 | 161 | – |
| 2447 | 27-JUL-08 08.59.10.223344 AM | direct | 101 | 8 | 33893.6 | 161 | – |
| 2432 | 14-SEP-07 09.53.40.223345 AM | direct | 102 | 10 | 10523 | 163 | – |
| 2433 | 13-SEP-07 10.19.00.654279 AM | direct | 103 | 10 | 78 | 163 | – |
| 2355 | 26-JAN-06 09.22.51.962632 AM | online | 104 | 8 | 94513.5 | – | – |
| 2356 | 26-JAN-08 09.22.41.934562 AM | online | 105 | 5 | 29473.8 | – | – |
| 2359 | 08-JAN-06 09.34.13.112233 PM | online | 106 | 9 | 5543.1 | – | – |
| 2360 | 14-NOV-07 12.22.31.223344 PM | online | 107 | 4 | 990.4 | – | – |
| 2361 | 13-NOV-07 01.34.21.986210 PM | online | 108 | 8 | 120131.3 | – | – |
| 2362 | 13-NOV-07 02.41.10.619477 PM | online | 109 | 4 | 92829.4 | – | – |
| 2363 | 23-OCT-07 05.49.56.346122 PM | online | 144 | 0 | 10082.3 | – | – |
| 2364 | 28-AUG-07 06.18.45.942399 PM | online | 145 | 4 | 9500 | – | – |
| 2365 | 28-AUG-07 07.03.34.003399 PM | online | 146 | 9 | 27455.3 | – | – |
| 2366 | 28-AUG-07 08.59.23.144778 PM | online | 147 | 5 | 37319.4 | – | – |
| 2367 | 27-JUN-08 09.53.32.335522 PM | online | 148 | 10 | 144054.8 | – | – |
| 2368 | 26-JUN-08 10.19.43.190089 PM | online | 149 | 10 | 60065 | – | – |
| 2369 | 26-JUN-07 11.22.54.009932 PM | online | 116 | 0 | 11097.4 | – | – |
| 2370 | 27-JUN-08 12.22.11.647398 AM | online | 117 | 4 | 126 | – | – |
| 2371 | 16-MAY-07 01.34.56.113356 AM | online | 118 | 6 | 79405.6 | – | – |
| 2372 | 27-FEB-07 12.22.33.356789 AM | online | 119 | 9 | 16447.2 | – | – |
| 2373 | 27-FEB-08 01.34.51.220065 AM | online | 120 | 4 | 416 | – | – |
| 2374 | 27-FEB-08 02.41.45.109654 AM | online | 121 | 0 | 4797 | – | – |
| 2375 | 26-FEB-07 03.49.50.459233 AM | online | 122 | 2 | 103834.4 | – | – |
| 2376 | 07-JUN-07 06.18.08.883310 AM | online | 123 | 6 | 11006.2 | – | – |
| 2377 | 07-JUN-07 07.03.01.001100 AM | online | 141 | 5 | 38017.8 | – | – |
| 2378 | 24-MAY-07 08.59.10.010101 AM | online | 142 | 5 | 25691.3 | – | – |
| 2380 | 16-MAY-07 09.53.02.909090 AM | online | 143 | 3 | 27132.6 | – | – |
| 2382 | 14-MAY-08 10.19.03.828321 AM | online | 144 | 8 | 71173 | – | – |
| 2383 | 12-MAY-08 11.22.30.545103 AM | online | 145 | 8 | 36374.7 | – | – |
| 2384 | 12-MAY-08 12.22.34.525972 PM | online | 146 | 3 | 29249.1 | – | – |
| 2385 | 08-DEC-07 11.34.11.331392 AM | online | 147 | 4 | 295892 | – | – |
| 2386 | 06-DEC-07 12.22.34.225609 PM | online | 148 | 10 | 21116.9 | – | – |
| 2387 | 11-MAR-07 03.34.56.536966 PM | online | 149 | 5 | 52758.9 | – | – |
| 2388 | 04-JUN-07 04.41.12.554435 PM | online | 150 | 4 | 282694.3 | – | – |
| 2389 | 04-JUN-08 05.49.43.546954 PM | online | 151 | 4 | 17620 | – | – |
| 2390 | 18-NOV-07 04.18.50.546851 PM | online | 152 | 9 | 7616.8 | – | – |
| 2391 | 27-FEB-06 05.03.03.828330 PM | direct | 153 | 2 | 48070.6 | 156 | – |
| 2392 | 21-JUL-07 08.59.57.571057 PM | direct | 154 | 9 | 26632 | 161 | – |
| 2393 | 10-FEB-08 07.53.19.528202 PM | direct | 155 | 4 | 23431.9 | 161 | – |
| 2395 | 02-FEB-06 08.19.11.227550 PM | direct | 156 | 3 | 68501 | 163 | – |
| 2398 | 19-NOV-07 09.22.53.224175 PM | direct | 157 | 9 | 7110.3 | 163 | – |
| 2399 | 19-NOV-07 10.22.38.340990 PM | direct | 158 | 0 | 25270.3 | 161 | – |
| 2400 | 10-JUL-07 01.34.29.559387 AM | direct | 159 | 2 | 69286.4 | 161 | – |
| 2401 | 10-JUL-07 02.22.53.554822 AM | direct | 160 | 3 | 969.2 | 163 | – |
| 2402 | 02-JUL-07 03.34.44.665170 AM | direct | 161 | 8 | 600 | 154 | – |
| 2403 | 01-JUL-07 04.49.13.615512 PM | direct | 162 | 0 | 220 | 154 | – |
| 2404 | 01-JUL-07 04.49.13.664085 PM | direct | 163 | 6 | 510 | 158 | – |
| 2405 | 01-JUL-07 04.49.13.678123 PM | direct | 164 | 5 | 1233 | 159 | – |
| 2407 | 29-JUN-07 07.03.21.526005 AM | direct | 165 | 9 | 2519 | 155 | – |
| 2408 | 29-JUN-07 08.59.31.333617 AM | direct | 166 | 1 | 309 | 158 | – |
| 2409 | 29-JUN-07 09.53.41.984501 AM | direct | 167 | 2 | 48 | 154 | – |
| 2410 | 24-MAY-08 10.19.51.985501 AM | direct | 168 | 6 | 45175 | 156 | – |
| 2411 | 24-MAY-07 11.22.10.548639 AM | direct | 169 | 8 | 15760.5 | 156 | – |
| 2412 | 29-MAR-06 10.22.09.509801 AM | direct | 170 | 9 | 66816 | 158 | – |
| 2413 | 29-MAR-08 01.34.04.525934 PM | direct | 101 | 5 | 48552 | 161 | – |
| 2414 | 29-MAR-07 02.22.40.536996 PM | direct | 102 | 8 | 10794.6 | 153 | – |
| 2415 | 29-MAR-06 01.34.50.545196 PM | direct | 103 | 6 | 310 | 161 | – |
| 2416 | 29-MAR-07 04.41.20.945676 PM | direct | 104 | 6 | 384 | 160 | – |
| 2417 | 20-MAR-07 05.49.10.974352 PM | direct | 105 | 5 | 1926.6 | 163 | – |
| 2418 | 20-MAR-04 04.18.21.862632 PM | direct | 106 | 4 | 5546.6 | 163 | – |
| 2419 | 20-MAR-07 07.03.32.764632 PM | direct | 107 | 3 | 31574 | 160 | – |
| 2420 | 13-MAR-07 08.59.43.666320 PM | direct | 108 | 2 | 29750 | 160 | – |
| 2421 | 12-MAR-07 09.53.54.562432 PM | direct | 109 | 1 | 72836 | – | – |
| 2422 | 16-DEC-07 08.19.55.462332 PM | direct | 144 | 2 | 11188.5 | 153 | – |
| 2423 | 21-NOV-07 10.22.33.362632 AM | direct | 145 | 3 | 10367.7 | 160 | – |
| 2424 | 21-NOV-07 10.22.33.263332 AM | direct | 146 | 4 | 13824 | 153 | – |
| 2425 | 16-NOV-06 11.34.22.162552 PM | direct | 147 | 5 | 1500.8 | 163 | – |
| 2426 | 17-NOV-06 12.22.11.262552 AM | direct | 148 | 6 | 7200 | – | – |
| 2427 | 10-NOV-07 01.34.22.362124 AM | direct | 149 | 7 | 9055 | 163 | – |
| 2428 | 10-NOV-07 02.41.34.463567 AM | direct | 116 | 8 | 14685.8 | – | – |
| 2429 | 10-NOV-07 03.49.25.526321 AM | direct | 117 | 9 | 50125 | 154 | – |
| 2430 | 02-OCT-07 06.18.36.663332 AM | direct | 101 | 8 | 29669.9 | 159 | – |
| 2431 | 14-SEP-06 07.03.04.763452 AM | direct | 102 | 1 | 5610.6 | 163 | – |
| 2437 | 01-SEP-06 08.59.15.826132 AM | direct | 103 | 4 | 13550 | 163 | – |
| 2438 | 01-SEP-07 09.53.26.934626 AM | direct | 104 | 0 | 5451 | 154 | – |
| 2439 | 31-AUG-07 10.19.37.811132 AM | direct | 105 | 1 | 22150.1 | 159 | – |
| 2441 | 01-AUG-08 11.22.48.734526 AM | direct | 106 | 5 | 2075.2 | 160 | – |
| 2442 | 27-JUL-06 12.22.59.662632 PM | direct | 107 | 9 | 52471.9 | 154 | – |
| 2443 | 27-JUL-06 01.34.16.562632 PM | direct | 108 | 0 | 3646 | 154 | – |
| 2444 | 27-JUL-07 02.22.27.462632 PM | direct | 109 | 1 | 77727.2 | 155 | – |
| 2445 | 27-JUL-06 03.34.38.362632 PM | direct | 144 | 8 | 5537.8 | 158 | – |
| 2448 | 18-JUN-07 04.41.49.262632 PM | direct | 145 | 5 | 1388 | 158 | – |
| 2449 | 13-JUN-07 05.49.07.162632 PM | direct | 146 | 6 | 86 | 155 | – |
| 2450 | 11-APR-07 06.18.10.362632 PM | direct | 147 | 3 | 1636 | 159 | – |
| 2451 | 17-DEC-07 05.03.52.562632 PM | direct | 148 | 7 | 10474.6 | 154 | – |
| 2452 | 06-OCT-07 08.59.43.462632 PM | direct | 149 | 5 | 12589 | 159 | – |
| 2453 | 04-OCT-07 09.53.34.362632 PM | direct | 116 | 0 | 129 | 153 | – |
| 2456 | 07-NOV-06 07.53.25.989889 PM | direct | 117 | 0 | 3878.4 | 163 | – |
| 2457 | 31-OCT-07 11.22.16.162632 PM | direct | 118 | 5 | 21586.2 | 159 | – |
Basic Usage
Sorting a result set is as easy as specifying the attribute you wish to sort by in the ORDER BY clause followed by “ASC” or “DESC.” These two keywords are short for ascending and descending, respectively. If the sorting method is omitted from the ORDER BY clause, then ascending order (ASC) is implied. As a word of caution, keep in mind making use of defaults in any programming language means you are operating under the assumption that the reader also knows the defaults. That said, you will notice I do make use of the default sort method in the examples on this page by not explicitly stating “ASC.”
Carrying on, let us see how easy it really is. The code below returns one row per job ID value and the average salary of the corresponding employees holding the specific job. The result set is sorted alphabetically in ascending (i.e., A-Z) order by the job ID values by using the ORDER BY clause followed by the pre-existing attribute, job_id.
SELECT
hr.employees.job_id,
AVG(hr.employees.salary) AS average_salary
FROM
hr.employees
GROUP BY
hr.employees.job_id
ORDER BY
hr.employees.job_id;
| job_id | average_salary |
|---|---|
| AC_ACCOUNT | 8300 |
| AC_MGR | 12008 |
| AD_ASST | 4400 |
| AD_PRES | 24000 |
| AD_VP | 17000 |
| FI_ACCOUNT | 7920 |
| FI_MGR | 12008 |
| HR_REP | 6500 |
| IT_PROG | 5760 |
| MK_MAN | 13000 |
| MK_REP | 6000 |
| PR_REP | 10000 |
| PU_CLERK | 2780 |
| PU_MAN | 11000 |
| SA_MAN | 12200 |
| SA_REP | 8350 |
| SH_CLERK | 3215 |
| ST_CLERK | 2785 |
| ST_MAN | 7280 |
With an additional four characters, the result set can be sorted in descending order. See the code and corresponding output below.
SELECT
hr.employees.job_id,
AVG(hr.employees.salary) AS average_salary
FROM
hr.employees
GROUP BY
hr.employees.job_id
ORDER BY
hr.employees.job_id DESC;
| job_id | average_salary |
|---|---|
| ST_MAN | 7280 |
| ST_CLERK | 2785 |
| SH_CLERK | 3215 |
| SA_REP | 8350 |
| SA_MAN | 12200 |
| PU_MAN | 11000 |
| PU_CLERK | 2780 |
| PR_REP | 10000 |
| MK_REP | 6000 |
| MK_MAN | 13000 |
| IT_PROG | 5760 |
| HR_REP | 6500 |
| FI_MGR | 12008 |
| FI_ACCOUNT | 7920 |
| AD_VP | 17000 |
| AD_PRES | 24000 |
| AD_ASST | 4400 |
| AC_MGR | 12008 |
| AC_ACCOUNT | 8300 |
In the previous examples, the result sets were sorted based on a single pre-existing attribute’s values. To sort a result set by multiple attributes, use the ORDER BY clause followed by a comma-separated list of attributes you wish to sort by. A concrete example can be found below. The code returns one row per manager ID and job ID combination along with the corresponding average employee salary. The result set is sorted by the manager ID values, ascending (i.e., least to greatest). Each group of grouped rows is subsequently sorted by the job ID values in descending order. For clarity, see the output following the code below.
SELECT
hr.employees.manager_id,
hr.employees.job_id,
AVG(hr.employees.salary) AS average_salary
FROM
hr.employees
GROUP BY
hr.employees.manager_id,
hr.employees.job_id
ORDER BY
hr.employees.manager_id,
hr.employees.job_id DESC;
| manager_id | job_id | average_salary |
|---|---|---|
| 100 | ST_MAN | 7280 |
| 100 | SA_MAN | 12200 |
| 100 | PU_MAN | 11000 |
| 100 | MK_MAN | 13000 |
| 100 | AD_VP | 17000 |
| 101 | PR_REP | 10000 |
| 101 | HR_REP | 6500 |
| 101 | FI_MGR | 12008 |
| 101 | AD_ASST | 4400 |
| 101 | AC_MGR | 12008 |
| 102 | IT_PROG | 9000 |
| 103 | IT_PROG | 4950 |
| 108 | FI_ACCOUNT | 7920 |
| 114 | PU_CLERK | 2780 |
| 120 | ST_CLERK | 2625 |
| 120 | SH_CLERK | 2900 |
| 121 | ST_CLERK | 2675 |
| 121 | SH_CLERK | 3675 |
| 122 | ST_CLERK | 2700 |
| 122 | SH_CLERK | 3200 |
| 123 | ST_CLERK | 3000 |
| 123 | SH_CLERK | 3475 |
| 124 | ST_CLERK | 2925 |
| 124 | SH_CLERK | 2825 |
| 145 | SA_REP | 8500 |
| 146 | SA_REP | 8500 |
| 147 | SA_REP | 7766.666666666666666666666666666666666667 |
| 148 | SA_REP | 8650 |
| 149 | SA_REP | 8333.333333333333333333333333333333333333 |
| 201 | MK_REP | 6000 |
| 205 | AC_ACCOUNT | 8300 |
| – | AD_PRES | 24000 |
In the output above, notice all grouped rows corresponding to the manager ID value of 100 are next to each other and the corresponding job ID values are in descending order (i.e., Z-A). This is no surprise given the code used to generate the output, but is useful to connect the dots on how multi-attribute sorting works using SQL.
Having walked through the ORDER BY clause’s basic usage through a handful of examples, let us now turn to sorting result sets by things other than pre-existing attributes.
ORDER BY Non-selected Attributes
The ORDER BY clause permits users to sort a result set based on values that can be derived using the result set but are not specified in the SELECT clause. For example, suppose you are tasked with generating a sales representative performance report. For each sales representative, the total number of orders placed by customers assisted by the corresponding sales representative and the total order total value are required. Additionally, the report needs to be sorted in descending order based on each sales representative’s average order total. The code below achieves this task by sorting based on the results of computing the average order total across each set of grouped rows (i.e., each sales representative’s orders).
SELECT
oe.orders.sales_rep_id,
COUNT(oe.orders.order_id) AS order_count,
SUM(oe.orders.order_total) AS total_order_total
FROM
oe.orders
WHERE
oe.orders.sales_rep_id IS NOT NULL
GROUP BY
oe.orders.sales_rep_id
ORDER BY
AVG(oe.orders.order_total) DESC;
| sales_rep_id | order_count | total_order_total |
|---|---|---|
| 161 | 13 | 661734.5 |
| 156 | 5 | 202617.6 |
| 155 | 5 | 134415.2 |
| 153 | 5 | 114215.7 |
| 158 | 7 | 156296.2 |
| 159 | 7 | 151167.2 |
| 154 | 10 | 171973.1 |
| 160 | 6 | 88238.4 |
| 163 | 12 | 128249.5 |
ORDER BY Alias
Being able to sort a result set by an attribute’s alias can engender more readable code and save you keystrokes at the same time. In the example code below, the result set has been sorted in descending order based on the derived attribute, order_count, instead of the code used to produce the attribute and its values (i.e., COUNT(oe.orders.order_id)). While the benefit of this feature may not be significant here, the benefit is evident for derived attributes with more lengthy code required to produce them.
SELECT
oe.orders.sales_rep_id,
COUNT(oe.orders.order_id) AS order_count,
SUM(oe.orders.order_total) AS total_order_total
FROM
oe.orders
WHERE
oe.orders.sales_rep_id IS NOT NULL
GROUP BY
oe.orders.sales_rep_id
ORDER BY
order_count DESC;
| sales_rep_id | order_count | total_order_total |
|---|---|---|
| 161 | 13 | 661734.5 |
| 163 | 12 | 128249.5 |
| 154 | 10 | 171973.1 |
| 159 | 7 | 151167.2 |
| 158 | 7 | 156296.2 |
| 160 | 6 | 88238.4 |
| 153 | 5 | 114215.7 |
| 156 | 5 | 202617.6 |
| 155 | 5 | 134415.2 |
Custom Sorting
There may be instances where it is required or desirable to sort values in ways that go beyond the standard methods of ascending order and descending order. For example, suppose you are designing a sign-up form for your new technology newsletter. To subscribe to the newsletter, customers must fill out the form containing various fields, including a field called “Country Name.” This field is meant to indicate where the customer resides. You believe the vast majority of your subscribers will be residents of the United States, so to make it easier for the majority to fill out the form, you wish to have the value, “United States of America,” appear as the first value in the field’s drop-down selector and all subsequent country name values to appear in alphabetical order. How can this be achieved using SQL? One method is to use a CASE expression to implement conditional logic. In the code below, a CASE expression is used to return 0 when the country ID is “US” and 1 for all other country ID values. Sorting the numeric values returned results in the value, United States of America, appearing in the first row. The second argument or attribute specified in the ORDER BY clause is country name. This is required to ensure all country name values following the first value (i.e., United Statues of America) are sorted in alphabetical order. If this second attribute was not included in the ORDER BY clause, then the remainder of country names would be in no particular order.
SELECT
hr.countries.country_name AS "Country Name"
FROM
hr.countries
ORDER BY
CASE
WHEN hr.countries.country_id = 'US'
THEN 0
ELSE 1
END,
hr.countries.country_name;
| Country Name |
|---|
| United States of America |
| Argentina |
| Australia |
| Belgium |
| Brazil |
| Canada |
| China |
| Denmark |
| Egypt |
| France |
| Germany |
| India |
| Israel |
| Italy |
| Japan |
| Kuwait |
| Malaysia |
| Mexico |
| Netherlands |
| Nigeria |
| Singapore |
| Switzerland |
| United Kingdom |
| Zambia |
| Zimbabwe |
Handling Missing Values
Depending on the relational database management system (RDBMS) being used, NULL may appear at the beginning or at the end of a result set. For the examples on this page, Oracle Database 19c is used. By default, queries written using Oracle database will return NULLs first when the sorting specified is ascending and last when descending order is specified. It may be easier to think of it this way: For columns of numeric data type, NULL is treated as the largest value and for columns of character data type, NULL is last in terms of alphabetical order. An example for each scenario follows. For clarity, the code and corresponding output is provided.
-- Number of employees corresponding to each manager ID value.
SELECT
hr.employees.manager_id,
COUNT(hr.employees.employee_id) AS employee_count
FROM
hr.employees
GROUP BY
hr.employees.manager_id
ORDER BY
hr.employees.manager_id;
| manager_id | employee_count |
|---|---|
| 100 | 14 |
| 101 | 5 |
| 102 | 1 |
| 103 | 4 |
| 108 | 5 |
| 114 | 5 |
| 120 | 8 |
| 121 | 8 |
| 122 | 8 |
| 123 | 8 |
| 124 | 8 |
| 145 | 6 |
| 146 | 6 |
| 147 | 6 |
| 148 | 6 |
| 149 | 6 |
| 201 | 1 |
| 205 | 1 |
| – | 1 |
Notice in the example above, the row corresponding to the single employee not reporting to a manager appears last. In the example below, the number of employees not belonging to a department appears first because the sorting specified is descending order.
-- Number of employees corresponding to each department name value.
SELECT
hr.departments.department_name,
COUNT(hr.employees.employee_id) AS employee_count
FROM
hr.employees
LEFT JOIN
hr.departments
ON hr.employees.department_id = hr.departments.department_id
GROUP BY
hr.departments.department_name
ORDER BY
hr.departments.department_name DESC;
| department_name | employee_count |
|---|---|
| – | 1 |
| Shipping | 45 |
| Sales | 34 |
| Purchasing | 6 |
| Public Relations | 1 |
| Marketing | 2 |
| IT | 5 |
| Human Resources | 1 |
| Finance | 6 |
| Executive | 3 |
| Administration | 1 |
| Accounting | 2 |
Knowledge Check
If you’d like to confirm your understanding on the ORDER BY clause and other fundamental concepts, consider solving a handful of my practice problems here.