sqlpostgresqlstringslpad

LPAD y RPAD en SQL: rellenar cadenas hasta un ancho fijo

Como usar LPAD y RPAD para rellenar cadenas a un ancho fijo, hacer zero-padding de ids y numeros de factura, y construir columnas de ancho fijo para exportaciones.

3 min de lecturaReferencesql · postgresql · strings · lpad · rpad · formatting

Cuando necesitas convertir 42 en 000042 o alinear nombres en una columna de ancho fijo, LPAD y RPAD son las herramientas. Son funciones de relleno: extienden un valor hasta una longitud objetivo agregando caracteres de relleno a la izquierda o a la derecha. Veamos los casos habituales y las trampas.

Firma y la idea basica

Ambas funciones reciben tres argumentos: la cadena de origen, la longitud objetivo y la cadena de relleno.

-- LPAD pads on the LEFT, RPAD pads on the RIGHT
SELECT LPAD('42', 6, '0')      AS padded_left,   -- '000042'
       RPAD('John', 10, '.')   AS padded_right;  -- 'John......'

Reglas clave:

  • LPAD(string, length, fill) agrega fill a la izquierda hasta que la cadena alcanza length.
  • RPAD(string, length, fill) hace lo mismo a la derecha.
  • El tercer argumento es opcional: el relleno por defecto es un espacio.
  • El primer argumento debe ser texto, asi que convierte primero las columnas numericas: id::text.
-- Cast numeric ids to text before padding
SELECT LPAD(id::text, 6, '0') AS user_code
FROM users
ORDER BY id
LIMIT 5;

Zero-padding de ids y numeros de factura

El caso mas frecuente son los codigos legibles con ceros a la izquierda. Un id de usuario 7 se convierte en USR-000007; un id de pedido se convierte en un numero de factura de formato fijo.

-- Build a stable user code like USR-000007
SELECT id,
       'USR-' || LPAD(id::text, 6, '0') AS user_code
FROM users
ORDER BY id;

-- Invoice numbers with a year prefix: INV-2026-000123
SELECT o.id,
       'INV-2026-' || LPAD(o.id::text, 6, '0') AS invoice_no
FROM orders o
WHERE o.status = 'paid'
ORDER BY o.id;

Por que rellenar con LPAD en vez de guardar la cadena ya formateada? El codigo siempre se deriva del id numerico, se mantiene ordenado como un numero y no ocupa almacenamiento extra. El formato es asunto de la capa de presentacion, no del almacenamiento.

Truncado: cuando la cadena es mas larga que el objetivo

La gran trampa: si la cadena de origen es mas larga que length, LPAD y RPAD no agrandan el resultado, lo truncan hasta la longitud objetivo. No se lanza ningun error.

-- The string is longer than the target -> it gets TRUNCATED
SELECT LPAD('1234567', 6, '0') AS clipped;  -- '123456', not '1234567'

Esto importa con los contadores: cuando un id llega a siete digitos, un campo de seis caracteres pierde en silencio el digito inicial. Protegete con una comprobacion explicita del ancho:

-- GREATEST guarantees the field never silently clips
SELECT LPAD(id::text, GREATEST(6, LENGTH(id::text)), '0') AS safe_code
FROM users;

Gotcha: la cadena de relleno puede tener mas de un caracter, y entonces se repite y se corta en el limite del caracter. LPAD('7', 5, 'ab') devuelve abab7: el relleno se cicla a la izquierda y los caracteres sobrantes se descartan.

Columnas de ancho fijo para exportaciones

Los sistemas heredados y los formatos bancarios suelen exigir ficheros con columnas de ancho fijo y sin separadores. Aqui RPAD alinea el texto a la izquierda y LPAD alinea los numeros a la derecha.

-- Fixed-width export line: name(20) + country(2) + amount(12)
SELECT RPAD(u.name, 20, ' ')
    || RPAD(u.country, 2, ' ')
    || LPAD(o.amount::text, 12, '0') AS export_line
FROM users u
JOIN orders o ON o.user_id = u.id
ORDER BY u.id;

Patrones utiles:

  • Los campos de texto (nombres, departamentos) se alinean a la izquierda con RPAD y relleno de espacios.
  • Los campos numericos (importes, cantidades) se alinean a la derecha con LPAD y relleno de ceros.
  • Recuerda el truncado: un name largo se cortara a 20 caracteres. Si eso es inaceptable, comprueba LENGTH(name) de antemano.
-- Pad employee names and right-align salary for a report
SELECT RPAD(name, 25, ' ') || LPAD(salary::text, 10, ' ') AS row_line
FROM employees
ORDER BY dept, name;

Diferencias con MySQL y ClickHouse

La sintaxis basica de LPAD/RPAD coincide entre PostgreSQL y MySQL, pero los detalles divergen:

  • En MySQL los tres argumentos de LPAD/RPAD son obligatorios: no hay relleno por defecto.
  • MySQL tambien trunca las cadenas mas largas que el objetivo.
  • MySQL es mas laxo con los tipos: a menudo convierte un numero a cadena de forma implicita, pero escribir CAST(id AS CHAR) es mas seguro.
-- MySQL: fill argument is required, cast id explicitly
SELECT LPAD(CAST(id AS CHAR), 6, '0') AS user_code
FROM users;

En ClickHouse las funciones se llaman leftPad y rightPad (con alias LPAD/RPAD), pero la logica es la misma:

-- ClickHouse: leftPad / rightPad
SELECT leftPad(toString(id), 6, '0') AS user_code
FROM users;

En resumen: LPAD rellena a la izquierda, RPAD a la derecha, con un espacio por defecto. Convierte los numeros a texto antes de rellenar, vigila el truncado silencioso de valores largos y usa estas funciones para generar codigos y exportaciones de ancho fijo, no para almacenar cadenas ya formateadas.

Practica con ejercicios reales

Resuelve ejercicios en el entrenador de SQL con corrección instantánea y pistas.

Abrir el entrenador