Quando voce precisa transformar 42 em 000042 ou alinhar nomes em uma coluna de largura fixa, LPAD e RPAD sao as ferramentas. Sao funcoes de preenchimento: estendem um valor ate um comprimento alvo adicionando caracteres de preenchimento a esquerda ou a direita. Vamos passar pelos casos comuns e pelas armadilhas.
Assinatura e a ideia basica
Ambas as funcoes recebem tres argumentos: a string de origem, o comprimento alvo e a string de preenchimento.
SELECT LPAD('42', 6, '0') AS padded_left,
RPAD('John', 10, '.') AS padded_right;
Regras principais:
LPAD(string, length, fill) adiciona fill a esquerda ate a string atingir length.
RPAD(string, length, fill) faz o mesmo a direita.
- O terceiro argumento e opcional: o preenchimento padrao e um espaco.
- O primeiro argumento precisa ser texto, entao converta as colunas numericas antes:
id::text.
SELECT LPAD(id::text, 6, '0') AS user_code
FROM users
ORDER BY id
LIMIT 5;
Zero-padding de ids e numeros de nota
O caso mais comum sao codigos legiveis com zeros a esquerda. Um id de usuario 7 vira USR-000007; um id de pedido vira um numero de nota de formato fixo.
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 preencher com LPAD em vez de guardar a string ja formatada? O codigo e sempre derivado do id numerico, continua ordenado como numero e nao gasta armazenamento extra. A formatacao e responsabilidade da camada de apresentacao, nao do armazenamento.
Truncamento: quando a string e mais longa que o alvo
A grande armadilha: se a string de origem for mais longa que length, LPAD e RPAD nao aumentam o resultado, eles o truncam ate o comprimento alvo. Nenhum erro e lancado.
SELECT LPAD('1234567', 6, '0') AS clipped;
Isso importa para contadores: quando um id chega a sete digitos, um campo de seis caracteres perde em silencio o digito inicial. Proteja-se com uma verificacao explicita de largura:
SELECT LPAD(id::text, GREATEST(6, LENGTH(id::text)), '0') AS safe_code
FROM users;
Gotcha: a string de preenchimento pode ter mais de um caractere e, nesse caso, ela e repetida e cortada no limite do caractere. LPAD('7', 5, 'ab') retorna abab7: o preenchimento cicla a esquerda e os caracteres excedentes sao descartados.
Colunas de largura fixa para exportacoes
Sistemas legados e formatos bancarios costumam exigir arquivos com colunas de largura fixa e sem delimitadores. Aqui o RPAD alinha o texto a esquerda e o LPAD alinha os numeros a direita.
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;
Padroes uteis:
- Campos de texto (nomes, departamentos) sao alinhados a esquerda com
RPAD e preenchimento de espacos.
- Campos numericos (valores, quantidades) sao alinhados a direita com
LPAD e preenchimento de zeros.
- Lembre do truncamento: um
name longo sera cortado em 20 caracteres. Se isso for inaceitavel, verifique LENGTH(name) antes.
SELECT RPAD(name, 25, ' ') || LPAD(salary::text, 10, ' ') AS row_line
FROM employees
ORDER BY dept, name;
Diferencas de MySQL e ClickHouse
A sintaxe basica de LPAD/RPAD coincide entre PostgreSQL e MySQL, mas os detalhes divergem:
- No MySQL os tres argumentos de
LPAD/RPAD sao obrigatorios: nao ha preenchimento padrao.
- O MySQL tambem trunca strings mais longas que o alvo.
- O MySQL e mais permissivo com tipos: um numero costuma ser convertido em string de forma implicita, mas escrever
CAST(id AS CHAR) e mais seguro.
SELECT LPAD(CAST(id AS CHAR), 6, '0') AS user_code
FROM users;
No ClickHouse as funcoes se chamam leftPad e rightPad (com aliases LPAD/RPAD), mas a logica e a mesma:
SELECT leftPad(toString(id), 6, '0') AS user_code
FROM users;
Resumo: LPAD preenche a esquerda, RPAD a direita, com um espaco por padrao. Converta numeros para texto antes de preencher, fique atento ao truncamento silencioso de valores longos e use essas funcoes para gerar codigos e exportacoes de largura fixa, nao para guardar strings ja formatadas.
Quando voce precisa transformar
42em000042ou alinhar nomes em uma coluna de largura fixa,LPADeRPADsao as ferramentas. Sao funcoes de preenchimento: estendem um valor ate um comprimento alvo adicionando caracteres de preenchimento a esquerda ou a direita. Vamos passar pelos casos comuns e pelas armadilhas.Assinatura e a ideia basica
Ambas as funcoes recebem tres argumentos: a string de origem, o comprimento alvo e a string de preenchimento.
-- 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......'Regras principais:
LPAD(string, length, fill)adicionafilla esquerda ate a string atingirlength.RPAD(string, length, fill)faz o mesmo a direita.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 e numeros de nota
O caso mais comum sao codigos legiveis com zeros a esquerda. Um id de usuario
7viraUSR-000007; um id de pedido vira um numero de nota de formato fixo.-- 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 preencher com
LPADem vez de guardar a string ja formatada? O codigo e sempre derivado doidnumerico, continua ordenado como numero e nao gasta armazenamento extra. A formatacao e responsabilidade da camada de apresentacao, nao do armazenamento.Truncamento: quando a string e mais longa que o alvo
A grande armadilha: se a string de origem for mais longa que
length,LPADeRPADnao aumentam o resultado, eles o truncam ate o comprimento alvo. Nenhum erro e lancado.-- The string is longer than the target -> it gets TRUNCATED SELECT LPAD('1234567', 6, '0') AS clipped; -- '123456', not '1234567'Isso importa para contadores: quando um id chega a sete digitos, um campo de seis caracteres perde em silencio o digito inicial. Proteja-se com uma verificacao explicita de largura:
-- GREATEST guarantees the field never silently clips SELECT LPAD(id::text, GREATEST(6, LENGTH(id::text)), '0') AS safe_code FROM users;Gotcha: a string de preenchimento pode ter mais de um caractere e, nesse caso, ela e repetida e cortada no limite do caractere.
LPAD('7', 5, 'ab')retornaabab7: o preenchimento cicla a esquerda e os caracteres excedentes sao descartados.Colunas de largura fixa para exportacoes
Sistemas legados e formatos bancarios costumam exigir arquivos com colunas de largura fixa e sem delimitadores. Aqui o
RPADalinha o texto a esquerda e oLPADalinha os numeros a direita.-- 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;Padroes uteis:
RPADe preenchimento de espacos.LPADe preenchimento de zeros.namelongo sera cortado em 20 caracteres. Se isso for inaceitavel, verifiqueLENGTH(name)antes.-- 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;Diferencas de MySQL e ClickHouse
A sintaxe basica de
LPAD/RPADcoincide entre PostgreSQL e MySQL, mas os detalhes divergem:LPAD/RPADsao obrigatorios: nao ha preenchimento padrao.CAST(id AS CHAR)e mais seguro.-- MySQL: fill argument is required, cast id explicitly SELECT LPAD(CAST(id AS CHAR), 6, '0') AS user_code FROM users;No ClickHouse as funcoes se chamam
leftPaderightPad(com aliasesLPAD/RPAD), mas a logica e a mesma:-- ClickHouse: leftPad / rightPad SELECT leftPad(toString(id), 6, '0') AS user_code FROM users;Resumo:
LPADpreenche a esquerda,RPADa direita, com um espaco por padrao. Converta numeros para texto antes de preencher, fique atento ao truncamento silencioso de valores longos e use essas funcoes para gerar codigos e exportacoes de largura fixa, nao para guardar strings ja formatadas.