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.
SELECT LPAD('42', 6, '0') AS padded_left,
RPAD('John', 10, '.') AS padded_right;
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.
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.
SELECT id,
'USR-' || LPAD(id::text, 6, '0') AS user_code
FROM users
ORDER BY id;
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.
SELECT LPAD('1234567', 6, '0') AS clipped;
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:
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.
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.
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.
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:
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.
Cuando necesitas convertir
42en000042o alinear nombres en una columna de ancho fijo,LPADyRPADson 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)agregafilla la izquierda hasta que la cadena alcanzalength.RPAD(string, length, fill)hace lo mismo a la derecha.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
7se convierte enUSR-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
LPADen vez de guardar la cadena ya formateada? El codigo siempre se deriva delidnumerico, 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,LPADyRPADno 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')devuelveabab7: 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
RPADalinea el texto a la izquierda yLPADalinea 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:
RPADy relleno de espacios.LPADy relleno de ceros.namelargo se cortara a 20 caracteres. Si eso es inaceptable, compruebaLENGTH(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/RPADcoincide entre PostgreSQL y MySQL, pero los detalles divergen:LPAD/RPADson obligatorios: no hay relleno por defecto.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
leftPadyrightPad(con aliasLPAD/RPAD), pero la logica es la misma:-- ClickHouse: leftPad / rightPad SELECT leftPad(toString(id), 6, '0') AS user_code FROM users;En resumen:
LPADrellena a la izquierda,RPADa 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.