Ordenar resultados: ORDER BY, LIMIT, DISTINCT

Intermedio
SQL
SQL
Actualizado: 02/09/2025

ORDER BY

La cláusula ORDER BY nos permite organizar los resultados de nuestras consultas de forma específica, controlando el orden en que aparecen las filas devueltas. Por defecto, las bases de datos no garantizan ningún orden particular en los resultados, por lo que esta cláusula resulta esencial cuando necesitamos presentar la información de manera estructurada.

La sintaxis básica de ORDER BY se coloca al final de la consulta SELECT y sigue esta estructura:

SELECT columnas
FROM tabla
ORDER BY columna [ASC|DESC];

Orden ascendente y descendente

El comportamiento por defecto de ORDER BY es ordenar de forma ascendente (ASC), lo que significa:

  • Para números: del menor al mayor (1, 2, 3...)
  • Para texto: orden alfabético (A, B, C...)
  • Para fechas: de la más antigua a la más reciente

Veamos ejemplos prácticos con una tabla de empleados:

-- Ordenar empleados por salario de menor a mayor (ascendente por defecto)
SELECT nombre, apellido, salario
FROM empleados
ORDER BY salario;

Para obtener el orden descendente (DESC), especificamos explícitamente esta opción:

-- Empleados con mayor salario primero
SELECT nombre, apellido, salario
FROM empleados
ORDER BY salario DESC;
-- Ordenar alfabéticamente por apellido de Z a A
SELECT nombre, apellido, departamento
FROM empleados
ORDER BY apellido DESC;

Ordenación por múltiples columnas

Una de las capacidades más útiles de ORDER BY es poder ordenar por varias columnas simultáneamente. El orden de prioridad sigue la secuencia en que listamos las columnas, separándolas por comas:

-- Primero por departamento, luego por salario descendente
SELECT nombre, apellido, departamento, salario
FROM empleados
ORDER BY departamento ASC, salario DESC;

En este ejemplo, SQL agrupa primero todos los empleados por departamento alfabéticamente, y dentro de cada departamento los ordena por salario de mayor a menor.

Ejemplo práctico con diferentes criterios de ordenación:

-- Ordenar por ciudad, luego por edad descendente, finalmente por nombre
SELECT nombre, apellido, ciudad, edad
FROM empleados
ORDER BY ciudad ASC, edad DESC, nombre ASC;

Uso de números de posición

SQL permite referenciar las columnas del ORDER BY mediante números de posición basados en el orden que aparecen en la cláusula SELECT:

-- Equivale a ORDER BY nombre, salario DESC
SELECT nombre, apellido, salario, departamento
FROM empleados
ORDER BY 1, 3 DESC;

Aunque esta funcionalidad existe, es recomendable usar nombres de columnas por razones de legibilidad y mantenimiento del código.

Combinación con WHERE

ORDER BY se combina perfectamente con las cláusulas WHERE que ya conocemos, ejecutándose después del filtrado:

-- Empleados del departamento IT ordenados por fecha de contratación
SELECT nombre, apellido, fecha_contratacion, salario
FROM empleados
WHERE departamento = 'IT'
ORDER BY fecha_contratacion ASC;
-- Empleados con salario superior a 50000, ordenados por experiencia
SELECT nombre, apellido, anos_experiencia, salario
FROM empleados
WHERE salario > 50000
ORDER BY anos_experiencia DESC, apellido ASC;

Ordenación de valores NULL

Los valores NULL requieren consideración especial en la ordenación. El comportamiento puede variar entre sistemas de gestión de bases de datos, pero generalmente:

  • En orden ascendente: los NULL aparecen al final
  • En orden descendente: los NULL aparecen al principio
-- Los empleados sin teléfono aparecerán según el comportamiento del SGBD
SELECT nombre, apellido, telefono
FROM empleados
ORDER BY telefono ASC;

Ordenación por expresiones

ORDER BY también acepta expresiones calculadas y funciones, no solo nombres de columnas:

-- Ordenar por el salario anual calculado
SELECT nombre, apellido, salario
FROM empleados
ORDER BY salario * 12 DESC;
-- Ordenar por la longitud del nombre
SELECT nombre, apellido
FROM empleados
ORDER BY LENGTH(nombre) DESC;

LIMIT

La cláusula LIMIT es una herramienta fundamental para controlar la cantidad de filas que devuelve una consulta SQL. Su propósito principal es restringir el número de resultados, lo que resulta especialmente útil cuando trabajamos con tablas grandes o cuando solo necesitamos una muestra representativa de los datos.

La sintaxis básica de LIMIT es sencilla y se coloca al final de la consulta SELECT:

SELECT columnas
FROM tabla
WHERE condiciones
ORDER BY columna
LIMIT numero_filas;

Uso básico de LIMIT

El caso más común es obtener un número específico de registros de una tabla. Por ejemplo, para ver solo los primeros 5 empleados de nuestra tabla:

-- Obtener los primeros 5 empleados
SELECT nombre, apellido, departamento
FROM empleados
LIMIT 5;

Esta consulta devuelve exactamente 5 filas, independientemente de cuántos empleados tenga la tabla. Es importante recordar que sin ORDER BY, el resultado puede variar entre ejecuciones, ya que las bases de datos no garantizan un orden específico.

Combinación con ORDER BY

La verdadera utilidad de LIMIT se manifiesta cuando la combinamos con ORDER BY para obtener resultados deterministas. Esta combinación nos permite extraer los "top N" elementos según un criterio específico:

-- Los 3 empleados con mayor salario
SELECT nombre, apellido, salario
FROM empleados
ORDER BY salario DESC
LIMIT 3;
-- Los 10 empleados más jóvenes
SELECT nombre, apellido, edad, fecha_contratacion
FROM empleados
ORDER BY edad ASC
LIMIT 10;

Paginación con OFFSET

Una funcionalidad avanzada de LIMIT es su combinación con OFFSET para implementar paginación. OFFSET indica cuántas filas saltar antes de empezar a contar para LIMIT:

-- Segunda página de resultados (filas 6-10)
SELECT nombre, apellido, departamento
FROM empleados
ORDER BY apellido ASC
LIMIT 5 OFFSET 5;
-- Tercera página de 10 empleados cada una (filas 21-30)
SELECT nombre, apellido, salario
FROM empleados
ORDER BY fecha_contratacion DESC
LIMIT 10 OFFSET 20;

La fórmula para paginación es: OFFSET = (numero_pagina - 1) * tamaño_pagina

LIMIT con subconsultas

LIMIT también funciona eficazmente en subconsultas para resolver problemas complejos:

-- Empleados con los 3 salarios más altos de cada departamento
SELECT nombre, apellido, departamento, salario
FROM empleados e1
WHERE (
    SELECT COUNT(*)
    FROM empleados e2
    WHERE e2.departamento = e1.departamento 
    AND e2.salario >= e1.salario
) <= 3
ORDER BY departamento, salario DESC;

Diferencias entre sistemas de gestión

Es crucial entender que LIMIT no es estándar SQL y su disponibilidad varía según el sistema de gestión de bases de datos:

  • MySQL, PostgreSQL, SQLite: Utilizan LIMIT
  • SQL Server: Utiliza TOP o OFFSET...FETCH
  • Oracle: Utiliza FETCH FIRST...ROWS ONLY o ROWNUM

Ejemplo equivalente en SQL Server:

-- SQL Server utiliza TOP
SELECT TOP 5 nombre, apellido, salario
FROM empleados
ORDER BY salario DESC;

Optimización de rendimiento

LIMIT contribuye significativamente a la optimización de consultas:

  • Reduce el uso de memoria al limitar los datos transferidos
  • Mejora los tiempos de respuesta especialmente en tablas grandes
  • Minimiza el tráfico de red entre la aplicación y la base de datos
-- Consulta optimizada para obtener solo lo necesario
SELECT nombre, apellido
FROM empleados
WHERE activo = true
ORDER BY fecha_contratacion DESC
LIMIT 50;

Buenas prácticas

Al utilizar LIMIT, es recomendable seguir estas mejores prácticas:

  • Siempre combinar con ORDER BY cuando el orden importe
  • Usar índices en las columnas del ORDER BY para mejor rendimiento
  • Considerar la paginación para interfaces de usuario
  • Evitar OFFSET grandes en producción por razones de rendimiento

DISTINCT

La cláusula DISTINCT es una herramienta fundamental para eliminar filas duplicadas de los resultados de una consulta SQL. Su función principal es garantizar que cada combinación única de valores aparezca solo una vez en el conjunto de resultados, lo que resulta especialmente útil cuando trabajamos con datos que pueden contener duplicados.

La sintaxis básica de DISTINCT es sencilla y se coloca inmediatamente después de SELECT:

SELECT DISTINCT columna1, columna2
FROM tabla
WHERE condiciones;

Funcionamiento básico

Cuando utilizamos DISTINCT en una columna individual, SQL devuelve únicamente los valores únicos de esa columna. Por ejemplo, para obtener una lista de todos los departamentos existentes en nuestra tabla de empleados:

-- Obtener lista única de departamentos
SELECT DISTINCT departamento
FROM empleados;

Si nuestra tabla contiene empleados de IT, Ventas, IT, Marketing, Ventas, la consulta devolvería solo: IT, Ventas, Marketing.

Ejemplo práctico para obtener todas las ciudades donde tenemos empleados:

-- Lista de ciudades únicas
SELECT DISTINCT ciudad
FROM empleados
ORDER BY ciudad;

DISTINCT con múltiples columnas

El verdadero valor de DISTINCT se manifiesta cuando trabajamos con múltiples columnas. En este caso, SQL considera la combinación completa de valores para determinar la unicidad:

-- Combinaciones únicas de departamento y ciudad
SELECT DISTINCT departamento, ciudad
FROM empleados
ORDER BY departamento, ciudad;

Esta consulta devuelve cada combinación única de departamento-ciudad. Si tenemos empleados de IT en Madrid y Barcelona, y de Ventas solo en Madrid, obtendremos tres filas: (IT, Barcelona), (IT, Madrid), (Ventas, Madrid).

Ejemplo más complejo que muestra combinaciones de datos:

-- Combinaciones únicas de puesto y nivel de experiencia
SELECT DISTINCT puesto, anos_experiencia, salario_rango
FROM empleados
WHERE activo = true
ORDER BY puesto, anos_experiencia;

Combinación con WHERE

DISTINCT se combina perfectamente con cláusulas WHERE para filtrar datos antes de eliminar duplicados:

-- Departamentos únicos donde hay empleados activos
SELECT DISTINCT departamento
FROM empleados
WHERE activo = true AND fecha_contratacion >= '2020-01-01';
-- Ciudades únicas donde tenemos empleados senior
SELECT DISTINCT ciudad, pais
FROM empleados
WHERE anos_experiencia >= 5
ORDER BY pais, ciudad;

DISTINCT con funciones agregadas

Una aplicación muy común de DISTINCT es su uso con funciones de agregación, especialmente COUNT():

-- Contar cuántos departamentos diferentes tenemos
SELECT COUNT(DISTINCT departamento) AS total_departamentos
FROM empleados;
-- Número de ciudades únicas por país
SELECT pais, COUNT(DISTINCT ciudad) AS ciudades_unicas
FROM empleados
GROUP BY pais
ORDER BY ciudades_unicas DESC;

Combinación con ORDER BY

DISTINCT funciona armoniosamente con ORDER BY, aplicándose primero la eliminación de duplicados y luego la ordenación:

-- Departamentos únicos ordenados alfabéticamente
SELECT DISTINCT departamento
FROM empleados
ORDER BY departamento ASC;
-- Combinaciones únicas ordenadas por múltiples criterios
SELECT DISTINCT ciudad, departamento
FROM empleados
ORDER BY ciudad ASC, departamento DESC;

Consideraciones de rendimiento

El uso de DISTINCT puede impactar el rendimiento de las consultas, especialmente en tablas grandes. Esto ocurre porque la base de datos debe:

  • Procesar todos los registros que cumplen las condiciones
  • Comparar cada fila con las anteriores para identificar duplicados
  • Ordenar o agrupar internamente los resultados

Alternativas más eficientes en algunos casos:

-- En lugar de DISTINCT, usar GROUP BY cuando sea posible
SELECT departamento
FROM empleados
WHERE activo = true
GROUP BY departamento
ORDER BY departamento;

Casos de uso comunes

DISTINCT resulta especialmente útil en escenarios específicos:

  • 1. Análisis de datos únicos:
-- Obtener lista de proveedores activos
SELECT DISTINCT proveedor_nombre, pais_origen
FROM productos
WHERE disponible = true;
  • 2. Validación de integridad:
-- Verificar cuántos emails únicos tenemos
SELECT COUNT(DISTINCT email) AS emails_unicos,
       COUNT(*) AS total_registros
FROM usuarios;
  • 3. Generación de listas de valores:
-- Categorías de productos para un formulario
SELECT DISTINCT categoria
FROM productos
WHERE activo = true
ORDER BY categoria;

Buenas prácticas

Al utilizar DISTINCT, es recomendable seguir estas mejores prácticas:

  • Evaluar la necesidad real: Solo usar DISTINCT cuando realmente existan duplicados
  • Combinar con índices: Asegurar que las columnas usadas tengan índices apropiados
  • Limitar resultados: Usar con LIMIT cuando sea posible para mejorar el rendimiento
  • Considerar alternativas: Evaluar si GROUP BY puede ser más eficiente
-- Ejemplo optimizado con LIMIT
SELECT DISTINCT categoria
FROM productos
WHERE fecha_creacion >= '2024-01-01'
ORDER BY categoria
LIMIT 20;

Fuentes y referencias

Documentación oficial y recursos externos para profundizar en SQL

Documentación oficial de SQL
Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, SQL es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de SQL

Explora más contenido relacionado con SQL y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

  • Comprender cómo usar ORDER BY para ordenar resultados de consultas SQL.
  • Aplicar LIMIT para restringir la cantidad de filas devueltas y manejar paginación.
  • Utilizar DISTINCT para eliminar filas duplicadas y obtener valores únicos.
  • Combinar estas cláusulas con otras como WHERE para consultas más precisas.
  • Conocer buenas prácticas y consideraciones de rendimiento al usar estas cláusulas.