Por defecto, SQL no garantiza ningún orden en los resultados. El motor devuelve las filas en el orden que le resulte más eficiente, que puede cambiar de una ejecución a otra. Para obtener resultados ordenados de forma predecible, se usa ORDER BY. Para limitar cuántas filas devuelve la consulta, se usa LIMIT.
Juntos, ORDER BY y LIMIT son la base para implementar listados ordenados y paginación en cualquier aplicación web.
ORDER BY: ordenar resultados
-- Ordenar por precio ascendente (ASC es el valor por defecto) SELECT nombre, precio FROM productos ORDER BY precio; SELECT nombre, precio FROM productos ORDER BY precio ASC; -- Ordenar por precio descendente (más caro primero) SELECT nombre, precio FROM productos ORDER BY precio DESC; -- Ordenar por ciudad y luego por nombre dentro de cada ciudad SELECT nombre, ciudad, fecha_alta FROM clientes ORDER BY ciudad ASC, nombre ASC;
ORDER BY con alias y expresiones
-- Puedes ordenar por un alias definido en el SELECT SELECT nombre, precio * stock AS valor_inventario FROM productos ORDER BY valor_inventario DESC; -- O por una expresión directamente SELECT nombre, precio FROM productos ORDER BY precio * 1.21 DESC; -- ordenar por precio con IVA
Valores NULL en ORDER BY
En MySQL, los NULL aparecen primero en orden ASC y al final en orden DESC. En PostgreSQL el comportamiento es el contrario por defecto, pero ambos motores permiten controlarlo:
-- MySQL: poner NULLs al final en orden ASC SELECT nombre, ciudad FROM clientes ORDER BY ciudad IS NULL ASC, ciudad ASC; -- PostgreSQL: NULLS FIRST / NULLS LAST SELECT nombre, ciudad FROM clientes ORDER BY ciudad ASC NULLS LAST;
LIMIT: restringir el número de filas
-- Los 5 productos más caros SELECT nombre, precio FROM productos ORDER BY precio DESC LIMIT 5; -- El producto más barato (LIMIT 1) SELECT nombre, precio FROM productos ORDER BY precio ASC LIMIT 1;
LIMIT con OFFSET: paginación
-- Sintaxis MySQL: LIMIT cantidad OFFSET saltar -- Página 1 (filas 1-10) SELECT nombre, precio FROM productos ORDER BY nombre LIMIT 10 OFFSET 0; -- Página 2 (filas 11-20) SELECT nombre, precio FROM productos ORDER BY nombre LIMIT 10 OFFSET 10; -- Página 3 (filas 21-30) SELECT nombre, precio FROM productos ORDER BY nombre LIMIT 10 OFFSET 20; -- Fórmula: OFFSET = (numero_pagina - 1) * filas_por_pagina
En aplicaciones reales, la paginación con OFFSET funciona bien hasta unos pocos miles de registros. En tablas grandes (millones de filas), un OFFSET alto es lento porque MySQL tiene que leer y descartar todas las filas anteriores. La alternativa eficiente es la paginación por cursor: guardar el último ID visto y usarlo en el WHERE:
-- Paginación por cursor: mucho más rápida en tablas grandes -- Primera página SELECT id, nombre, precio FROM productos ORDER BY id ASC LIMIT 20; -- Siguiente página: usar el último id de la página anterior como cursor SELECT id, nombre, precio FROM productos WHERE id > :ultimo_id_visto ORDER BY id ASC LIMIT 20;
TOP en SQL Server
SQL Server y MS Access usan TOP n en lugar de LIMIT:
-- SQL Server SELECT TOP 5 nombre, precio FROM productos ORDER BY precio DESC; -- Oracle (hasta 11g) SELECT nombre, precio FROM productos WHERE ROWNUM <= 5 ORDER BY precio DESC;
La sintaxis LIMIT está estandarizada en SQL:2008 y la soportan MySQL, PostgreSQL, SQLite y MariaDB. Para SQL Server usa TOP o FETCH FIRST ... ROWS ONLY (SQL Server 2012+).
