Arrays y seriessolo PostgreSQL

GENERATE_SERIES

Crea filas con una secuencia de números o de momentos.

Sintaxis

GENERATE_SERIES(<inicio>, <fin>)
GENERATE_SERIES(<inicio>, <fin>, <paso>)

Genera filas desde el inicio hasta el fin, ambos incluidos, con el paso indicado: los números 1, 2, 3… o fechas día a día. No hace falta ninguna tabla. Lo más habitual es usarla para tener un calendario completo y mostrar en un informe incluso los días o meses en los que no pasó nada.

Datos para los ejemplos

orders

idcreated_atamount
12026-07-03 10:15:00120.50
22026-07-28 18:40:0080.25
32026-08-09 09:05:00199.99
42026-08-21 14:30:0045.00
52026-09-02 11:00:0064.75

Estas tablas ya están creadas en el entorno de pruebas y los ejemplos de abajo las usan. ¿Quieres repetirlo en tu propia base de datos? Copia el SQL.

Números del 1 al 5
SELECT GENERATE_SERIES(1, 5) AS n;
n
1
2
3
4
5
Con paso
SELECT GENERATE_SERIES(0, 100, 25) AS percent;
percent
0
25
50
75
100
Cada día de una semana
SELECT day::date AS day
FROM GENERATE_SERIES(TIMESTAMP '2026-09-07', TIMESTAMP '2026-09-13', INTERVAL '1 day') AS day;
day
2026-09-07
2026-09-08
2026-09-09
2026-09-10
2026-09-11
2026-09-12
2026-09-13
Pedidos por meses, incluidos los vacíosAvanzado
SELECT month_start::date AS month,
COUNT(o.id) AS order_count
FROM GENERATE_SERIES(TIMESTAMP '2026-06-01', TIMESTAMP '2026-09-01', INTERVAL '1 month') AS month_start
LEFT JOIN orders o ON DATE_TRUNC('month', o.created_at) = month_start
GROUP BY month_start
ORDER BY month_start;
monthorder_count
2026-06-010
2026-07-012
2026-08-012
2026-09-011

En junio no hubo pedidos, pero el mes está en el informe: LEFT JOIN lo conserva y COUNT(o.id) da 0.

Ten en cuenta

El fin entra en el resultado: GENERATE_SERIES(1, 5) da 5 filas.

Si el inicio es mayor que el fin y el paso es positivo, no hay ninguna fila. Para contar hacia atrás, usa un paso negativo: GENERATE_SERIES(5, 1, -1).

Para las fechas, el paso como intervalo es obligatorio. Y si pasas un DATE, el resultado pasa a ser timestamp with time zone y dependerá de la zona horaria; por eso los ejemplos usan TIMESTAMP y ::date.

Funciones relacionadas

Más detalles en el curso