sqlpostgresqlstringslpad

LPAD e RPAD no SQL: preencher strings ate uma largura fixa

Como usar LPAD e RPAD para preencher strings ate uma largura fixa, fazer zero-padding de ids e numeros de nota, e montar colunas de largura fixa para exportacoes.

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

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.

-- 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) 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.
-- 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 7 vira USR-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 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.

-- 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') 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.

-- 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:

  • 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.
-- 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/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.
-- 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 leftPad e rightPad (com aliases LPAD/RPAD), mas a logica e a mesma:

-- ClickHouse: leftPad / rightPad
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.

Pratique com exercícios reais

Resolva exercícios no treinador de SQL com correção instantânea e dicas.

Abrir o treinador