ORDER BY
Cuando ejecutas un SELECT sin especificar un orden, MySQL no garantiza en qué secuencia devuelve las filas. En la práctica suelen aparecer en el orden en que se insertaron, pero esto no es fiable y puede cambiar según el motor de almacenamiento, los índices o las actualizaciones que se hayan hecho. Si necesitas un orden específico, debes usar ORDER BY.
Sintaxis
SELECT columnas
FROM tabla
WHERE condicion
ORDER BY columna1 [ASC | DESC], columna2 [ASC | DESC], ...;La cláusula ORDER BY se escribe después del WHERE (si lo hay). Puedes ordenar por una o varias columnas, y para cada una especificar si el orden es ascendente (ASC) o descendente (DESC). Si no indicas dirección, MySQL usa ASC por defecto.
Orden ascendente
Ordenar los productos por precio de menor a mayor:
SELECT nombre, precio
FROM productos
ORDER BY precio;| nombre | precio |
|---|---|
| 1984 | 12.99 |
| Cien años de soledad | 14.99 |
| El nombre del viento | 16.99 |
| Cable USB-C a Lightning | 19.99 |
| Banda elástica set x5 | 19.99 |
| Camiseta algodón básica | 24.99 |
| ... | ... |
| ASUS ROG Zephyrus | 1899.99 |
Como no indicamos ASC ni DESC, MySQL ordena de forma ascendente. Los productos más baratos aparecen primero. Observa que hay dos productos con precio 19.99: cuando varios registros tienen el mismo valor en la columna de ordenación, su orden relativo es indeterminado.
Orden descendente
Para invertir el orden, añade DESC:
SELECT nombre, precio
FROM productos
ORDER BY precio DESC;| nombre | precio |
|---|---|
| ASUS ROG Zephyrus | 1899.99 |
| Lenovo ThinkPad X1 | 1549.00 |
| MacBook Air M3 | 1399.00 |
| iPhone 15 Pro | 1299.99 |
| Samsung Galaxy S24 | 899.99 |
| Google Pixel 8 | 699.00 |
| ... | ... |
| 1984 | 12.99 |
Ahora los productos más caros aparecen primero. DESC viene de "descending" (descendente).
Ordenar por múltiples columnas
Cuando ordenas por varias columnas, MySQL aplica el orden de izquierda a derecha. Primero ordena por la primera columna, y cuando hay empates, usa la segunda columna para desempatar:
SELECT nombre, puesto, salario
FROM empleados
ORDER BY salario DESC, nombre ASC;| nombre | puesto | salario |
|---|---|---|
| Ricardo | Director General | 75000.00 |
| Sofía | Directora de Ventas | 55000.00 |
| Alberto | Director de Logística | 52000.00 |
| Natalia | Vendedora Senior | 38000.00 |
| Cristina | Responsable de Almacén | 35000.00 |
| Daniel | Vendedor | 32000.00 |
| Patricia | Vendedora | 32000.00 |
| Raúl | Vendedor Junior | 28000.00 |
| Inés | Operaria de Almacén | 26000.00 |
| Marcos | Operario de Almacén | 26000.00 |
Los empleados se ordenan por salario de mayor a menor. Daniel y Patricia ganan lo mismo (32000), así que MySQL los desempata alfabéticamente por nombre (ASC). Lo mismo ocurre con Inés y Marcos (26000).
Cada columna puede tener su propia dirección. En este ejemplo, salario es DESC pero nombre es ASC.
Ordenar por texto
Cuando ordenas por una columna de texto, MySQL aplica un orden alfabético según la collation configurada. Con la collation por defecto (utf8mb4_0900_ai_ci), el orden no distingue mayúsculas y minúsculas ni acentos:
SELECT nombre, ciudad
FROM clientes
ORDER BY ciudad;| nombre | ciudad |
|---|---|
| Lucía | A Coruña |
| Carlos | Barcelona |
| Laura | Barcelona |
| Alejandro | Bilbao |
| Fernando | Burgos |
| Miguel | Córdoba |
| ... | ... |
| Javier | Zaragoza |
| Elena | Zaragoza |
Las ciudades aparecen en orden alfabético. Barcelona tiene dos clientes, cuyo orden entre sí no está garantizado (a menos que añadas una segunda columna de ordenación).
Ordenar por expresiones
Puedes ordenar por el resultado de una expresión, no solo por columnas directas:
SELECT nombre, precio, stock, precio * stock AS valor_inventario
FROM productos
ORDER BY precio * stock DESC;| nombre | precio | stock | valor_inventario |
|---|---|---|---|
| iPhone 15 Pro | 1299.99 | 45 | 58499.55 |
| Samsung Galaxy S24 | 899.99 | 62 | 55799.38 |
| Xiaomi 14 | 599.99 | 80 | 47999.20 |
| MacBook Air M3 | 1399.00 | 25 | 34975.00 |
| Lenovo ThinkPad X1 | 1549.00 | 18 | 27882.00 |
| ASUS ROG Zephyrus | 1899.99 | 12 | 22799.88 |
| ... | ... | ... | ... |
A diferencia del WHERE, en el ORDER BY sí puedes usar alias definidos en el SELECT. Esto es porque MySQL procesa el ORDER BY después del SELECT:
SELECT nombre, precio * stock AS valor_inventario
FROM productos
ORDER BY valor_inventario DESC;Esta consulta produce el mismo resultado que la anterior. Usar el alias es más legible y evita repetir la expresión.
Ordenar por posición ordinal
Puedes referirte a las columnas del SELECT por su posición numérica en lugar de por su nombre:
SELECT nombre, precio
FROM productos
ORDER BY 2 DESC;El número 2 se refiere a la segunda columna del SELECT, que es precio. Esta forma es más concisa pero menos legible, y puede causar errores difíciles de detectar si alguien reordena las columnas del SELECT. Úsala solo para consultas rápidas en la terminal, nunca en código de aplicación.
Ordenar por columna no seleccionada
Puedes ordenar por una columna que no aparece en el SELECT:
SELECT nombre, precio
FROM productos
ORDER BY stock DESC;| nombre | precio |
|---|---|
| Camiseta algodón básica | 24.99 |
| Cable USB-C a Lightning | 19.99 |
| Funda iPhone silicona | 49.99 |
| Banda elástica set x5 | 19.99 |
| Camiseta técnica running | 34.99 |
| Cargador USB-C 65W | 35.99 |
| ... | ... |
El resultado está ordenado por stock descendente, aunque la columna stock no aparece en la salida. MySQL puede acceder a cualquier columna de la tabla para ordenar, independientemente de las que muestre.
ORDER BY con WHERE
Cuando combinas WHERE y ORDER BY, primero se filtran las filas y después se ordenan las que quedan:
SELECT nombre, precio, stock
FROM productos
WHERE precio < 50
ORDER BY precio DESC;| nombre | precio | stock |
|---|---|---|
| Sartén antiadherente 28cm | 39.99 | 75 |
| Clean Code | 39.99 | 55 |
| Cargador USB-C 65W | 35.99 | 150 |
| Camiseta técnica running | 34.99 | 180 |
| Eloquent JavaScript | 34.99 | 42 |
| Esterilla yoga premium | 29.99 | 100 |
| Diseño de APIs | 29.99 | 60 |
| Camiseta algodón básica | 24.99 | 500 |
| Cable USB-C a Lightning | 19.99 | 300 |
| Banda elástica set x5 | 19.99 | 200 |
| El nombre del viento | 16.99 | 70 |
| Cien años de soledad | 14.99 | 85 |
| 1984 | 12.99 | 110 |
El WHERE reduce los 30 productos a 13, y el ORDER BY los ordena por precio descendente.
Valores NULL en la ordenación
MySQL trata los valores NULL como los más bajos posibles en el orden. Con ASC, los NULL aparecen primero. Con DESC, aparecen al final:
SELECT nombre, telefono
FROM clientes
ORDER BY telefono ASC;| nombre | telefono |
|---|---|
| Paula | NULL |
| Marta | NULL |
| Alejandro | NULL |
| Miguel | 601234567 |
| Diego | 601234568 |
| María | 612345678 |
| ... | ... |
Los tres clientes sin teléfono (NULL) aparecen al principio. Si quisieras que los NULL aparezcan al final con orden ascendente, podrías usar un truco:
SELECT nombre, telefono
FROM clientes
ORDER BY telefono IS NULL, telefono ASC;La expresión telefono IS NULL devuelve 1 para los NULL y 0 para los demás. Al ordenar primero por esta expresión (0 antes que 1), los registros con valor aparecen primero y los NULL quedan al final.
Orden de procesamiento
Con ORDER BY, el orden completo de procesamiento es:
- FROM: identifica la tabla.
- WHERE: filtra filas.
- SELECT: evalúa expresiones y alias.
- ORDER BY: ordena el resultado.
El ORDER BY es la última operación, por eso puede usar alias del SELECT.
Practica con ORDER BY
Usa el editor para experimentar con distintas ordenaciones. Prueba a ordenar por varias columnas, combinar ASC y DESC, o usar expresiones:
En el siguiente artículo veremos cómo limitar el número de filas en el resultado con LIMIT.
Escrito por Eduardo Lázaro
