sqlpostgresqlstringleft

LEFT e RIGHT no SQL: primeiros e ultimos caracteres de uma string no PostgreSQL

Como LEFT e RIGHT pegam os primeiros ou ultimos N caracteres de uma string no PostgreSQL: mascarar cartoes, prefixos, comprimento negativo e comparacao com SUBSTRING.

3 min de leituraReferencesql · postgresql · string · left · right · mysql

Quando voce precisa dos tres primeiros digitos de um codigo ou dos quatro ultimos de um telefone, recorrer a um SUBSTRING prolixo e exagero. O PostgreSQL oferece duas funcoes curtas: LEFT pega caracteres do inicio da string e RIGHT pega do final. Vamos percorre-las na pratica e, de quebra, encontrar suas arestas afiadas.

Sintaxe basica

As duas funcoes recebem uma string e uma quantidade de caracteres: LEFT(string, n) e RIGHT(string, n). Elas contam caracteres, nao bytes, entao UTF-8 nao e problema.

SELECT LEFT('PROMO-2026', 5)  AS head,   -- 'PROMO'
       RIGHT('PROMO-2026', 4) AS tail;    -- '2026'

Em uma tabela real isso e pratico para extrair prefixos e sufixos. Digamos que orders.status guarde uma string como paid-eu e voce queira as primeiras letras do status:

SELECT id,
       LEFT(status, 4) AS status_head
FROM orders
LIMIT 5;

Propriedades principais:

  • O tipo do resultado e text.
  • Se n for maior que o comprimento da string, voce recebe a string inteira, sem erro e sem preenchimento.
  • Uma entrada NULL produz uma saida NULL.

Mascarar um numero de cartao

O caso classico e mostrar apenas os quatro ultimos digitos de um cartao de pagamento e esconder o resto. Aqui RIGHT e exatamente a ferramenta:

SELECT RIGHT('4111111111114242', 4) AS last4;   -- '4242'

Para obter o formato familiar **** 4242, concatene uma mascara com a cauda. Suponha que exista uma coluna com o numero do cartao do usuario:

SELECT u.id,
       '**** ' || RIGHT(card_number, 4) AS masked_card
FROM users u
JOIN payment_methods pm ON pm.user_id = u.id;

Da mesma forma, LEFT ajuda a extrair o BIN, os seis primeiros digitos que identificam o banco emissor:

SELECT LEFT(card_number, 6) AS bin
FROM payment_methods;

Gotcha: LEFT e RIGHT cortam caracteres, nao partes "logicas". Se o numero tiver espacos ou hifens (4111 1111 1111 4242), RIGHT(..., 4) retorna 4242 apenas se a cauda estiver limpa. Remova primeiro os separadores com REPLACE, senao voce pode mostrar por acidente um espaco em vez de um digito.

Comprimento negativo

Este e o recurso mais subestimado. Se voce passar um n negativo, o PostgreSQL conta caracteres a partir da ponta oposta e retorna o restante.

  • LEFT(s, -k) retorna a string sem seus ultimos k caracteres.
  • RIGHT(s, -k) retorna a string sem seus primeiros k caracteres.
SELECT LEFT('order-12345', -5)  AS without_tail,   -- 'order-'
       RIGHT('order-12345', -6) AS without_head;     -- '12345'

Isso brilha quando voce conhece o comprimento da parte a cortar mas nao o da string. Por exemplo, remover um sufixo de dominio fixo ou tirar um prefixo conhecido. Mas cuidado: se -k for maior em modulo que o comprimento da string, voce recebe uma string vazia '', nao NULL, entao e facil perder dados em silencio.

LEFT e RIGHT versus SUBSTRING

SUBSTRING e mais poderoso, porem mais verboso. Qualquer LEFT/RIGHT pode ser expresso com ele:

-- LEFT(name, 3) is equivalent to:
SELECT SUBSTRING(name FROM 1 FOR 3) FROM users;

-- RIGHT(name, 3) is equivalent to:
SELECT SUBSTRING(name FROM length(name) - 3 + 1) FROM users;

Repare que o equivalente de RIGHT obriga voce a calcular length() na mao e facilita erros de um a mais ou a menos. Entao a regra e simples:

  • Precisa de um prefixo ou sufixo fixo: use LEFT ou RIGHT, o codigo se le na hora.
  • Precisa de um pedaco do meio ou uma posicao dinamica: use SUBSTRING.
  • Precisa cortar por um padrao em vez de por comprimento: olhe para split_part ou expressoes regulares.

Um exemplo realista: agrupar funcionarios pela primeira letra do departamento com LEFT, bem mais limpo que SUBSTRING:

SELECT LEFT(dept, 1) AS dept_initial,
       count(*)       AS people
FROM employees
GROUP BY LEFT(dept, 1)
ORDER BY dept_initial;

MySQL e ClickHouse

Boa noticia: LEFT e RIGHT existem no MySQL com a mesma sintaxe LEFT(str, len) e RIGHT(str, len), entao as consultas migram quase sem ajustes.

  • O MySQL nao suporta comprimento negativo: LEFT('abc', -1) retorna uma string vazia, nao "tudo exceto o ultimo caractere". Essa e a diferenca principal ao migrar.
  • O ClickHouse tambem tem left e right; um argumento negativo ali funciona como no PostgreSQL, contando a partir do final.
  • No MySQL as duas funcoes contam caracteres conforme o conjunto de caracteres atual da coluna, o que costuma coincidir com o comportamento do PostgreSQL para UTF-8.
-- Works identically in PostgreSQL and MySQL
SELECT LEFT(email, 3)  AS prefix,
       RIGHT(email, 3) AS suffix
FROM users;

Resumo: LEFT e RIGHT sao a forma mais rapida de pegar a borda de uma string. Lembre do comprimento negativo como "cortar pela outra ponta", sempre limpe os separadores antes de mascarar e tenha em mente que o argumento negativo nao funciona no MySQL.

Pratique com exercícios reais

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

Abrir o treinador