SQL

Tutorial SQL: Paginación con LIMIT y OFFSET

Aprende a usar LIMIT y OFFSET en SQL para paginar resultados y optimizar consultas en bases de datos grandes de forma eficiente.

Aprende SQL y certifícate

LIMIT

La cláusula LIMIT es una herramienta fundamental en SQL que permite controlar el número de filas que se devuelven en una consulta. Esta funcionalidad resulta especialmente útil cuando trabajamos con tablas que contienen miles o millones de registros y solo necesitamos ver una pequeña muestra de los datos.

Sintaxis básica

La sintaxis de LIMIT es sencilla y directa:

SELECT columna1, columna2, ...
FROM tabla
LIMIT número_de_filas;

Donde número_de_filas es un valor entero positivo que indica cuántos registros queremos recuperar como máximo.

Casos de uso comunes

Obtener los primeros N registros

Uno de los usos más frecuentes de LIMIT es recuperar solo los primeros registros de una tabla:

-- Obtener los 5 primeros productos
SELECT id, nombre, precio
FROM productos
LIMIT 5;

Este ejemplo devolverá como máximo 5 filas, independientemente de cuántos productos existan en la tabla.

Combinación con ORDER BY

LIMIT se utiliza a menudo junto con ORDER BY para obtener los "N mejores" o "N peores" resultados:

-- Obtener los 3 productos más caros
SELECT id, nombre, precio
FROM productos
ORDER BY precio DESC
LIMIT 3;
-- Obtener los 5 clientes más recientes
SELECT id, nombre, fecha_registro
FROM clientes
ORDER BY fecha_registro DESC
LIMIT 5;

Es importante destacar que LIMIT siempre se aplica después de que los datos han sido ordenados, lo que garantiza que obtenemos exactamente los registros que necesitamos.

Consideraciones importantes

Orden de ejecución

En una consulta SQL, LIMIT se ejecuta casi al final del proceso, después de:

  1. FROM y JOIN (para determinar las tablas de origen)
  2. WHERE (para filtrar filas)
  3. GROUP BY (para agrupar filas)
  4. HAVING (para filtrar grupos)
  5. SELECT (para seleccionar columnas)
  6. ORDER BY (para ordenar resultados)

Esto significa que LIMIT simplemente "recorta" el conjunto de resultados final.

Rendimiento

El uso de LIMIT puede mejorar significativamente el rendimiento de las consultas, especialmente en tablas grandes:

-- Sin LIMIT: potencialmente procesa millones de filas
SELECT id, nombre FROM usuarios;

-- Con LIMIT: solo procesa 10 filas
SELECT id, nombre FROM usuarios LIMIT 10;

La segunda consulta será mucho más rápida, ya que el motor de base de datos puede dejar de procesar filas una vez que ha encontrado el número solicitado.

Diferencias entre MySQL y PostgreSQL

Aunque la sintaxis básica de LIMIT es similar en MySQL y PostgreSQL, existen algunas diferencias sutiles:

  • En MySQL, se puede usar la sintaxis alternativa LIMIT offset, count:
-- MySQL: obtener 5 registros empezando por el 11º
SELECT * FROM productos LIMIT 10, 5;
  • En PostgreSQL, esta sintaxis no está disponible, y se debe usar LIMIT count OFFSET offset:
-- PostgreSQL: obtener 5 registros empezando por el 11º
SELECT * FROM productos LIMIT 5 OFFSET 10;

Sin embargo, ambos sistemas soportan la sintaxis LIMIT count OFFSET offset, por lo que es recomendable usar esta forma para mantener la compatibilidad.

Ejemplos prácticos

Limitar resultados en consultas de análisis

-- Obtener los 10 productos más vendidos
SELECT p.nombre, SUM(d.cantidad) as total_vendido
FROM productos p
JOIN detalles_venta d ON p.id = d.producto_id
GROUP BY p.nombre
ORDER BY total_vendido DESC
LIMIT 10;

Limitar resultados en subconsultas

-- Obtener información detallada de los 5 clientes con más compras
SELECT c.id, c.nombre, c.email, COUNT(v.id) as total_compras
FROM clientes c
JOIN ventas v ON c.id = v.cliente_id
WHERE c.id IN (
    SELECT cliente_id
    FROM ventas
    GROUP BY cliente_id
    ORDER BY COUNT(*) DESC
    LIMIT 5
)
GROUP BY c.id, c.nombre, c.email
ORDER BY total_compras DESC;

Uso con funciones de agregación

-- Obtener las 3 categorías con mayor promedio de precio
SELECT categoria, AVG(precio) as precio_promedio
FROM productos
GROUP BY categoria
ORDER BY precio_promedio DESC
LIMIT 3;

El uso adecuado de LIMIT no solo mejora el rendimiento de las consultas, sino que también facilita la presentación de datos en interfaces de usuario, donde mostrar todos los registros de una tabla grande sería impracticable. En la siguiente sección, veremos cómo combinar LIMIT con OFFSET para implementar la paginación de resultados.

Paginación con OFFSET

La paginación es una técnica esencial cuando trabajamos con grandes conjuntos de datos en SQL. Mientras que LIMIT nos permite restringir el número de filas devueltas, OFFSET nos permite saltar un número específico de filas antes de comenzar a devolver resultados. Juntos, estos comandos forman la base de la paginación en aplicaciones de bases de datos.

Sintaxis básica de OFFSET

La sintaxis para usar OFFSET junto con LIMIT es:

SELECT columna1, columna2, ...
FROM tabla
LIMIT número_de_filas OFFSET posición_inicial;

Donde:

  • número_de_filas: Cantidad de registros a devolver (tamaño de página)
  • posición_inicial: Número de filas a omitir antes de comenzar a devolver resultados

Implementación de paginación

La paginación divide los resultados en "páginas" de tamaño fijo, permitiendo a los usuarios navegar a través de grandes conjuntos de datos de manera manejable.

Cálculo de OFFSET

Para implementar la paginación, necesitamos calcular el valor de OFFSET basado en el número de página y el tamaño de página:

OFFSET = (número_de_página - 1) * tamaño_de_página

Por ejemplo, si queremos mostrar 10 registros por página:

  • Página 1: OFFSET 0 (0-9)
  • Página 2: OFFSET 10 (10-19)
  • Página 3: OFFSET 20 (20-29)

Ejemplos prácticos

Supongamos que tenemos una tabla de productos con cientos de registros y queremos implementar una paginación con 15 productos por página:

-- Página 1 (primeros 15 productos)
SELECT id, nombre, precio
FROM productos
ORDER BY nombre
LIMIT 15 OFFSET 0;

-- Página 2 (productos 16-30)
SELECT id, nombre, precio
FROM productos
ORDER BY nombre
LIMIT 15 OFFSET 15;

-- Página 3 (productos 31-45)
SELECT id, nombre, precio
FROM productos
ORDER BY nombre
LIMIT 15 OFFSET 30;

En una aplicación real, el número de página sería una variable:

-- Donde página = 3 y tamaño_página = 15
SELECT id, nombre, precio
FROM productos
ORDER BY nombre
LIMIT 15 OFFSET ((3 - 1) * 15);

Paginación en interfaces de usuario

La paginación es especialmente útil en interfaces web donde mostrar todos los resultados a la vez sería abrumador para el usuario e ineficiente para el servidor:

-- Para una tabla de resultados de búsqueda
SELECT p.id, p.nombre, p.descripcion, p.precio
FROM productos p
WHERE p.nombre LIKE '%smartphone%'
ORDER BY p.precio ASC
LIMIT 20 OFFSET 40;  -- Tercera página (registros 41-60)

Este patrón se utiliza en prácticamente todas las aplicaciones que muestran listas de elementos, desde tiendas online hasta motores de búsqueda.

Consideraciones de rendimiento

Eficiencia en tablas grandes

Aunque OFFSET es muy útil, puede presentar problemas de rendimiento en tablas muy grandes:

-- Esta consulta puede ser lenta en tablas grandes
SELECT id, nombre
FROM clientes
ORDER BY id
LIMIT 20 OFFSET 10000;

Esto ocurre porque la base de datos debe escanear y descartar las primeras 10,000 filas antes de devolver las 20 solicitadas.

Alternativas para tablas grandes

Para tablas muy grandes, existen enfoques alternativos más eficientes:

-- Usando filtros basados en el último ID visto
SELECT id, nombre
FROM clientes
WHERE id > 10000  -- ID del último elemento de la página anterior
ORDER BY id
LIMIT 20;

Este método conocido como "seek method" o "keyset pagination" es más eficiente porque utiliza índices para saltar directamente a la posición deseada.

Diferencias entre MySQL y PostgreSQL

Tanto MySQL como PostgreSQL soportan la sintaxis LIMIT ... OFFSET ..., pero existen algunas diferencias:

  • MySQL permite una sintaxis alternativa donde el offset va primero:
-- Sintaxis alternativa en MySQL (no recomendada por compatibilidad)
SELECT * FROM productos LIMIT 10000, 20;  -- OFFSET 10000, LIMIT 20
  • PostgreSQL solo admite la sintaxis estándar:
SELECT * FROM productos LIMIT 20 OFFSET 10000;

Para mantener la compatibilidad entre sistemas, es recomendable usar siempre la sintaxis LIMIT ... OFFSET ....

Paginación con información adicional

En aplicaciones reales, a menudo necesitamos proporcionar información adicional sobre la paginación, como el número total de registros o páginas:

-- Consulta para obtener el total de registros
SELECT COUNT(*) as total_registros
FROM productos
WHERE categoria = 'electrónica';

-- Consulta para obtener la página actual de resultados
SELECT id, nombre, precio
FROM productos
WHERE categoria = 'electrónica'
ORDER BY precio
LIMIT 15 OFFSET 30;

Con estos dos valores, una aplicación puede calcular:

  • Número total de páginas: CEIL(total_registros / tamaño_página)
  • Si hay página siguiente: (página_actual * tamaño_página) < total_registros
  • Si hay página anterior: página_actual > 1

Ejemplo completo de implementación

Veamos un ejemplo completo de cómo implementar la paginación en una consulta más compleja:

-- Parámetros de paginación
-- @página: 3
-- @tamaño_página: 10

-- Consulta para obtener el total de registros
SELECT COUNT(*) as total
FROM productos p
JOIN categorias c ON p.categoria_id = c.id
WHERE c.nombre = 'Smartphones' AND p.precio BETWEEN 200 AND 800;

-- Consulta paginada
SELECT p.id, p.nombre, p.marca, p.precio, p.stock
FROM productos p
JOIN categorias c ON p.categoria_id = c.id
WHERE c.nombre = 'Smartphones' AND p.precio BETWEEN 200 AND 800
ORDER BY p.precio ASC, p.nombre ASC
LIMIT 10 OFFSET 20;  -- Página 3 con 10 elementos por página

Esta combinación de consultas proporciona toda la información necesaria para implementar una interfaz de paginación completa y funcional.

La paginación con OFFSET es una herramienta esencial en el desarrollo de aplicaciones que manejan grandes volúmenes de datos, permitiendo presentar la información de manera organizada y eficiente tanto para los usuarios como para el rendimiento del sistema.

Aprende SQL online

Otros ejercicios de programación de SQL

Evalúa tus conocimientos de esta lección Paginación con LIMIT y OFFSET con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Tipos de datos

Test

Inserción de datos: INSERT INTO

Test

Filtrado de grupos de resultados con HAVING

Test

Uso de índices y particiones

Test

Renombrar tablas y bases de datos: RENAME

Test

Uso de vistas

Test

Uso de INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL JOIN

Test

Agrupación de resultados con GROUP BY

Test

Creación y uso de subqueries

Test

Sentencias INSERT

Código

Copias de seguridad y restauración de bases de datos

Test

Uso de INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL JOIN

Código

Instalación de MySQL

Test

Relaciones entre tablas

Código

Eliminación de datos: DELETE

Test

Creación de bases de datos y tablas: CREATE DATABASE, CREATE TABLE

Test

Creación y uso de funciones

Test

Creación de tablas e inserción de datos con SQL

Proyecto

Uso de funciones agregadas: COUNT, SUM, AVG, MAX, MIN

Test

Optimización de consultas

Test

Introducción a SQL

Test

Triggers y eventos

Test

Clasificación de resultados con ORDER BY

Test

Alterar la estructura de tablas existentes: ALTER TABLE

Test

Eliminación de datos: DELETE

Código

Instalación de PostgreSQL

Test

Creación y uso de procedimientos almacenados

Test

Consultas básicas de selección: SELECT y WHERE

Test

Vaciar tablas y bases de datos: DROP

Test

Actualización de datos: UPDATE

Test

Creación y manejo de usuarios y roles

Test

Consultas básicas de selección SELECT y WHERE

Código

Creación de bases de datos y tablas

Código

Bases de datos y tablas

Test

Actualización de datos: UPDATE

Código

Relaciones entre tablas

Test

Filtrado de valores únicos con DISTINCT

Test

Asignación y gestión de permisos

Test

Todas las lecciones de SQL

Accede a todas las lecciones de SQL y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Introducción A Sql

Introducción Y Entorno

Ddl Y Dml

Introducción Y Entorno

Instalación De Mysql

Introducción Y Entorno

Instalación De Postgresql

Introducción Y Entorno

Tipos De Datos

Introducción Y Entorno

Bases De Datos Y Tablas

Introducción Y Entorno

Sistemas De Gestión De Bases De Datos

Introducción Y Entorno

Tipos De Bases De Datos

Introducción Y Entorno

Creación De Bases De Datos Y Tablas: Create Database, Create Table

Sintaxis Dml Crud

Consultas Básicas De Selección: Select Y Where

Sintaxis Dml Crud

Inserción De Datos: Insert Into

Sintaxis Dml Crud

Actualización De Datos: Update

Sintaxis Dml Crud

Eliminación De Datos: Delete

Sintaxis Dml Crud

Introducción A Dml

Sintaxis Dml Crud

Consultar Datos: Select

Sintaxis Dml Crud

Clasificación De Resultados Con Order By

Filtros Y Clasificación

Filtrado De Valores Únicos Con Distinct

Filtros Y Clasificación

Paginación Con Limit Y Offset

Filtros Y Clasificación

Alterar La Estructura De Tablas Existentes: Alter Table

Sintaxis Ddl

Renombrar Tablas Y Bases De Datos: Rename

Sintaxis Ddl

Vaciar Tablas Y Bases De Datos: Drop

Sintaxis Ddl

Uso De Funciones Agregadas: Count, Sum, Avg, Max, Min

Funciones Y Agrupación

Agrupación De Resultados Con Group By

Funciones Y Agrupación

Filtrado De Grupos De Resultados Con Having

Funciones Y Agrupación

Funciones Numéricas Y Matemáticas

Funciones Y Agrupación

Funciones De Fecha Y Hora

Funciones Y Agrupación

Funciones De Texto

Funciones Y Agrupación

Many To One

Asociaciones Entre Tablas

One To Many

Asociaciones Entre Tablas

One To One

Asociaciones Entre Tablas

Many To Many

Asociaciones Entre Tablas

Relaciones Entre Tablas

Joins Y Subqueries

Uso De Inner Join, Left Join, Right Join, Full Join

Joins Y Subqueries

Creación Y Uso De Subqueries

Joins Y Subqueries

Left Join Y Right Join

Joins Y Subqueries

Full Join

Joins Y Subqueries

Cross Join Y Self Join

Joins Y Subqueries

Optimización De Consultas

Sintaxis Avanzada

Uso De Índices Y Particiones

Sintaxis Avanzada

Uso De Vistas

Sintaxis Avanzada

Triggers Y Eventos

Sintaxis Avanzada

Particiones

Sintaxis Avanzada

Restricciones E Integridad

Sintaxis Avanzada

Transacciones

Sintaxis Avanzada

Vistas Materializadas

Sintaxis Avanzada

Rollback

Sintaxis Avanzada

Vistas Con Create View

Sintaxis Avanzada

Principios Acid

Sintaxis Avanzada

Manejo De Errores Y Excepciones

Sintaxis Avanzada

Funciones Ventana

Sintaxis Avanzada

Índices

Sintaxis Avanzada

Expresiones De Tabla Comunes (Cte) Con With

Sintaxis Avanzada

Creación Y Uso De Funciones

Programación En Sql

Creación Y Uso De Procedimientos Almacenados

Programación En Sql

Variables Y Control De Flujo

Programación En Sql

Creación Y Manejo De Usuarios Y Roles

Seguridad Y Administración

Asignación Y Gestión De Permisos

Seguridad Y Administración

Copias De Seguridad Y Restauración De Bases De Datos

Seguridad Y Administración

Accede GRATIS a SQL y certifícate

En esta lección

Objetivos de aprendizaje de esta lección

  • Comprender la función y sintaxis básica de la cláusula LIMIT en SQL.
  • Aprender a combinar LIMIT con ORDER BY para obtener subconjuntos específicos de datos.
  • Entender cómo OFFSET permite saltar filas y junto con LIMIT facilita la paginación.
  • Conocer las diferencias en la sintaxis y uso de LIMIT y OFFSET entre MySQL y PostgreSQL.
  • Identificar consideraciones de rendimiento y alternativas para paginación en tablas grandes.