SQL LIKE

Uma cliente liga para a Loja Aurora: "é a Ana, já comprei aí". Ana de quê? A atendente não sabe o nome completo, então o = não serve: nome = 'Ana' só acharia alguém chamado exatamente "Ana", e ninguém se chama assim. Ela precisa procurar por um pedaço do texto: "nomes que começam com Ana". É para isso que serve o LIKE ("parecido com", em inglês): ele compara o texto com um padrão, em vez de exigir que seja igualzinho.

Você vai aprender
  • Procurar textos que começam com, terminam com ou contêm um pedaço, usando o %.
  • Que, no SQLite, o LIKE ignora maiúsculas e minúsculas, mas só nas letras sem acento: 'a' LIKE 'A' dá verdadeiro, 'á' LIKE 'Á' dá falso.
  • O NOT LIKE e o que acontece com NULL e com números.
  • Como procurar um % ou um _ de verdade, com ESCAPE.
  • O GLOB, a alternativa do SQLite que diferencia maiúsculas.
  • Os erros mais comuns, com as mensagens reais.

Os exemplos usam o banco da Loja Aurora, e cada quadro "Resultado" vem do SQLite de verdade, rodando no seu navegador. Os dois "curingas" do LIKE, o % e o _, aparecem aqui só no básico; todas as combinações estão na próxima aula, Curingas (% e _).


A ideia: o "qualquer coisa"

No LIKE, o padrão é um texto comum com um símbolo especial: o % (sinal de porcentagem), que quer dizer "qualquer coisa aqui" (qualquer sequência de letras, de qualquer tamanho, até nenhuma). É como dizer à atendente: "procure 'Ana', seguido de um espaço, seguido de qualquer coisa".

O que a Ana querPadrãoLê-se
Começa com "Ana "'Ana %'"Ana ", depois qualquer coisa
Termina com "Azul"'%Azul'Qualquer coisa, depois "Azul"
Tem "de" em algum lugar'%de%'Qualquer coisa, "de", qualquer coisa
É exatamente "Ana"'Ana'Sem %, o LIKE funciona como um = (quase: veja a seção 3)

Há um segundo curinga, o _ (sublinhado), que quer dizer "exatamente uma letra qualquer". Ele é o assunto da próxima aula.


1. O primeiro LIKE

SELECT nome, cidade
FROM clientes
WHERE nome LIKE 'Ana %';
nome
A coluna de texto que vai ser comparada.
LIKE
"Parecido com": compara com um padrão, não com um valor exato.
'Ana %'
O padrão, entre aspas simples (é um texto). "Ana", um espaço e depois qualquer coisa.

Duas clientes: Ana Beatriz Sousa, de São Paulo, e Ana Carvalho Lima, de Teresina. Agora a atendente pode perguntar "a senhora é de São Paulo ou de Teresina?".

Por que o espaço depois de "Ana"? Sem ele, 'Ana%' também acharia uma "Anabela" ou uma "Anastácia". Com o espaço, só quem tem "Ana" como primeiro nome inteiro.

Compare com o =, que não conhece curingas:

SELECT nome
FROM clientes
WHERE nome = 'Ana %';

Nenhuma linha. Para o =, o % é só um caractere comum: ele procurou alguém chamado literalmente "Ana %".


2. Começa com, termina com, contém

A posição do % decide o tipo de busca. Os produtos que começam com "Garrafa":

SELECT nome
FROM produtos
WHERE nome LIKE 'Garrafa%';

Os que terminam com "azul" (repare: escrevi em minúsculas, e veio "Azul"; a seção 3 explica):

SELECT nome
FROM produtos
WHERE nome LIKE '%azul';

E os que contêm o número de telefone de Teresina, o DDD 86, entre parênteses, no começo:

SELECT nome, telefone
FROM fornecedores
WHERE telefone LIKE '(86)%';

Experimente: a consulta abaixo procura um produto chamado exatamente "Jogo" e não acha nada. Use LIKE para achar os produtos cujo nome começa com "Jogo" (são 2).

SELECT nome, preco
FROM produtos
WHERE nome = 'Jogo';
SELECT nome, preco
FROM produtos
WHERE nome LIKE 'Jogo%';

3. Maiúsculas, minúsculas e acentos

No SQLite, o LIKE não diferencia maiúsculas de minúsculas. Por isso 'ana %', 'Ana %' e 'ANA %' acham as mesmas duas clientes:

SELECT nome, cidade
FROM clientes
WHERE nome LIKE 'ana %';

Mas há uma pegadinha, e ela é grande para quem escreve em português. A documentação do SQLite avisa: por padrão, ele só entende maiúsculas e minúsculas das letras ASCII, ou seja, de A a Z, sem acento. Para as letras acentuadas (á, ã, ç, é, ô…), o LIKE diferencia maiúscula de minúscula. Veja letra por letra:

SELECT 'a' LIKE 'A', 'á' LIKE 'Á', 'ç' LIKE 'Ç', 'Água' LIKE 'água', 'Água' LIKE 'ÁGUA';
ComparaçãoResultadoPor quê
'a' LIKE 'A'1 (verdadeiro)"a" é ASCII: maiúscula e minúscula são a mesma letra para o LIKE.
'á' LIKE 'Á'0 (falso)Com acento, não é ASCII: "á" e "Á" são letras diferentes.
'ç' LIKE 'Ç'0 (falso)O mesmo com o cedilha.
'Água' LIKE 'água'0 (falso)O "Á" não casa com o "á"; o resto nem importa.
'Água' LIKE 'ÁGUA'1 (verdadeiro)O "Á" é igual nos dois lados, e "gua" × "GUA" são ASCII.

Na prática, com os dados da loja: o fornecedor 2 se chama Loja D'Água, com "Á" maiúsculo. A Ana procura por "água", em minúsculas:

SELECT nome
FROM fornecedores
WHERE nome LIKE '%água%';

Nada! O mesmo acontece com a cidade de São Paulo: cidade LIKE 'são paulo' acha os 7 clientes (o "ã" está igual, minúsculo, nos dois lados), mas cidade LIKE 'SÃO PAULO' não acha nenhum, porque "Ã" maiúsculo não casa com o "ã" guardado. E o acento em si sempre conta: '%agua%', sem acento, também não acha a Loja D'Água.

Como contornar
  • Escreva a parte acentuada do jeito que está guardada: '%Água%'.
  • Ou procure só pela parte sem acento: '%gua%' acha a Loja D'Água.
  • Para bancos com muita busca por texto, existe a extensão ICU do SQLite (citada na documentação), que ensina maiúsculas e minúsculas de todas as letras. Ela não vem no SQLite padrão, nem no editor do guia.

Missão: a busca abaixo não acha o fornecedor Loja D'Água por causa do acento. Mude só o padrão do LIKE para que ele apareça.

SELECT nome, cidade
FROM fornecedores
WHERE nome LIKE '%água%';
SELECT nome, cidade
FROM fornecedores
WHERE nome LIKE '%Água%';

4. NOT LIKE, NULL e números

NOT LIKE: o que não combina

Com NOT antes do LIKE (aula NOT), você fica com o que não combina. Os clientes cujo nome não termina com "a":

SELECT nome
FROM clientes
WHERE nome NOT LIKE '%a';

22 clientes; os outros 8 (José Ribamar Silva, Ana Beatriz Sousa, Carlos Eduardo Lima…) terminam com "a".

NULL não combina com nada

O padrão '%' combina com qualquer texto, até o texto vazio. Então quantos clientes têm um email que combina com '%'?

SELECT count(*)
FROM clientes
WHERE email LIKE '%';

27, e não 30. Os 3 clientes sem email (NULL) ficaram de fora: o NULL não é um texto, é "não sei", e "não sei" não combina com padrão nenhum. E eles também não aparecem no NOT LIKE: a armadilha é a mesma da aula NOT. (O count(*) conta as linhas; ele tem aula própria, COUNT().)

LIKE em números

O LIKE foi feito para texto, mas o SQLite aceita uma coluna de números: ele transforma o número em texto antes de comparar. Os produtos cujo preço termina em ",9":

SELECT nome, preco
FROM produtos
WHERE preco LIKE '%.9';

Funciona, mas é um truque: ele depende de como o número vira texto (4.9, e não 4.90). Para números, prefira as comparações (>, <, BETWEEN).


5. ESCAPE: procurando um % ou um _ de verdade

E se o texto que você procura tem um % ou um _? Por exemplo, um aviso "50% de desconto", ou um email com sublinhado (joao_silva@…). Dentro do padrão, esses símbolos são curingas, e o LIKE não os trata como letras. Veja a Ana procurando emails que têm um sublinhado:

SELECT count(*)
FROM clientes
WHERE email LIKE '%_%';

27, ou seja, todos os emails. Mas nenhum email da loja tem sublinhado! O que aconteceu: o _ do padrão é o curinga "uma letra qualquer", então '%_%' quer dizer "tem pelo menos uma letra", e todo email tem.

Para dizer "este _ é um sublinhado de verdade", escolha um caractere de escape com ESCAPE e ponha-o antes do símbolo:

SELECT count(*)
FROM clientes
WHERE email LIKE '%!_%' ESCAPE '!';
ESCAPE '!'
Avisa: neste padrão, o ! é o caractere de escape. Você escolhe qual; tem de ser um caractere só, que não apareça no texto procurado. !, \ e # são escolhas comuns.
!_
"Um _ de verdade", e não o curinga.
% … %
Continuam sendo curingas: "qualquer coisa" antes e depois.

Agora deu 0: de fato, nenhum email da loja tem sublinhado. Com o % é igual. Como a loja não tem nenhum texto com "%", veja o LIKE aplicado direto a textos de exemplo:

SELECT '50% de desconto' LIKE '50!%%' ESCAPE '!',
       '50 reais de desconto' LIKE '50!%%' ESCAPE '!',
       '50 reais de desconto' LIKE '50%';

O padrão '50!%%' quer dizer "50, um sinal de % de verdade, depois qualquer coisa": casa com "50% de desconto" (1) e não com "50 reais" (0). Sem o escape, '50%' casa com qualquer coisa que comece com 50, inclusive "50 reais" (1).

O SQLite não tem escape "de fábrica"

Sem a palavra ESCAPE, nenhum caractere é de escape no SQLite: '\%' é uma barra seguida do curinga. É o que manda o padrão SQL. Alguns bancos usam a barra invertida \ como escape automático (veja Nos outros bancos).


6. GLOB: a alternativa que diferencia maiúsculas

O SQLite tem um "primo" do LIKE, o GLOB (de global, o nome que o Unix dá para os padrões de nomes de arquivo, como *.txt). Ele faz o mesmo tipo de busca, com duas diferenças: os curingas são outros, e ele diferencia maiúsculas de minúsculas.

LIKEGLOB
Qualquer sequência%*
Exatamente um caractere_?
Um caractere de uma listanão tem[abc], [0-9]
Maiúsculas e minúsculasIguais (só A–Z sem acento)Diferentes, sempre
Existe em outros bancos?Sim, é padrão SQLNão, é só do SQLite
SELECT nome
FROM clientes
WHERE nome GLOB 'Ana *';

As mesmas duas clientes, mas agora com * no lugar de %. E com 'ana *', em minúsculas, o GLOB não acharia ninguém. A grande vantagem do GLOB são as listas entre colchetes. Os produtos que têm algum algarismo no nome:

SELECT nome
FROM produtos
WHERE nome GLOB '*[0-9]*';

[0-9] quer dizer "um caractere entre 0 e 9". Com o LIKE, não dá para dizer isso.


7. Formas diferentes de procurar

BuscaEscritaObservação
Igual, exatamentenome = 'Atlas Geográfico'Diferencia maiúsculas; não tem curingas
Começa comnome LIKE 'Atlas%'Ignora maiúsculas (A–Z)
Começa com, diferenciando maiúsculasnome GLOB 'Atlas*'Só no SQLite
Contém um de dois pedaçosnome LIKE '%Azul%' OR nome LIKE '%Amarelo%'Um LIKE para cada pedaço, unidos com OR
Contém um algarismonome GLOB '*[0-9]*'Listas só no GLOB
SituaçãoQual usar
Você sabe o valor inteiro= (é mais rápido e mais claro)
Você sabe só um pedaço, e maiúsculas não importamLIKE
Maiúsculas importam, ou você precisa de [0-9]GLOB (só SQLite)
O texto procurado tem % ou _LIKE … ESCAPE '!'
SQL que precisa rodar em outros bancosLIKE, sem GLOB

Quando dá errado

O padrão entre aspas duplas
SELECT nome FROM clientes WHERE nome LIKE "Ana%";

A mensagem: no such column: "Ana%" - should this be a string literal in single-quotes?, "não existe a coluna "Ana%"; isto deveria ser um texto entre aspas simples?". O próprio SQLite dá a dica: aspas duplas são para nomes (de coluna, de tabela), e ele foi procurar uma coluna chamada Ana%.

Como consertar: o padrão é um texto: LIKE 'Ana%'.

O padrão sem aspas
SELECT nome FROM clientes WHERE nome LIKE Ana%;

A mensagem: near ";": syntax error. Sem aspas, o SQLite leu Ana como uma coluna e o % como a conta "resto da divisão", que precisa de um número depois. Chegou no ; sem o número.

ESCAPE com mais de um caractere
SELECT nome FROM clientes WHERE nome LIKE 'Ana%' ESCAPE '!!';

A mensagem: ESCAPE expression must be a single character, "a expressão do ESCAPE tem de ser um único caractere".

Usou * no LIKE
SELECT nome FROM clientes WHERE nome LIKE 'Ana*';

O que aconteceu: nenhuma mensagem e nenhuma linha. O * é curinga do GLOB (e da busca de arquivos do Windows e do Linux), não do LIKE. Para o LIKE, ele é um asterisco comum, e ninguém se chama "Ana*".

Como consertar: no LIKE, o curinga é o %: LIKE 'Ana%'.

Esqueceu o %

WHERE nome LIKE 'Ana' devolve 0 linhas, sem erro. Sem curinga, o LIKE só aceita o texto inteiro ("Ana", e nada mais). Se a ideia é "começa com", falta o % no fim.

O acento que não casa

Também sem erro: nome LIKE '%água%' não acha "Loja D'Água", e nome LIKE '%CONCEIÇÃO%' não acha "Conceição Prado". O LIKE do SQLite só ignora maiúsculas nas letras sem acento (seção 3).

Nos outros bancos

O LIKE com %, _ e ESCAPE é padrão SQL e existe em todos. A diferença está em maiúsculas, acentos e escape:

Banco'ana' LIKE 'Ana'Observação
SQLiteVerdadeiroIgnora maiúsculas só de A a Z; acentuadas diferenciam
PostgreSQLFalsoO LIKE diferencia maiúsculas; para ignorar, use ILIKE (extensão do PostgreSQL, que segue a língua configurada). A barra \ é o escape automático.
MySQLDepende da collationCom a padrão do MySQL 8 (utf8mb4_0900_ai_ci), ignora maiúsculas e acentos
SQL ServerDepende da collationAceita também [abc] e [^abc] dentro do LIKE, como o GLOB

Ilustrativo (não roda no SQLite):

-- PostgreSQL: LIKE diferencia maiúsculas; ILIKE não
SELECT nome FROM clientes WHERE nome ILIKE 'ana %';

-- SQL Server: lista de caracteres dentro do LIKE
SELECT nome FROM produtos WHERE nome LIKE '%[0-9]%';

O GLOB não existe fora do SQLite.


Referência rápida

EscritaO que faz
coluna LIKE 'abc%'Começa com "abc"
coluna LIKE '%abc'Termina com "abc"
coluna LIKE '%abc%'Contém "abc"
coluna NOT LIKE '%abc%'Não contém "abc" (linhas com NULL ficam de fora)
coluna LIKE '%!%%' ESCAPE '!'Contém um % de verdade
coluna GLOB 'Abc*'Começa com "Abc", diferenciando maiúsculas (só SQLite)
'a' LIKE 'A' / 'á' LIKE 'Á'1 / 0 no SQLite
Mensagem do SQLiteQuer dizer
no such column: "Ana%" - should this be a string literal in single-quotes?Padrão entre aspas duplas
near ";": syntax errorPadrão sem aspas
ESCAPE expression must be a single characterESCAPE com mais de um caractere

Exercícios

1. Começa com

Complete o padrão para achar os produtos que começam com "Caixa":

SELECT nome FROM produtos WHERE nome LIKE 'Caixa';

2. A palavra certa

Complete com o operador que compara com um padrão:

SELECT nome FROM clientes WHERE cidade 'Forta%';

3. No SQLite, qual destas comparações dá falso?

4. A tabela tem 30 clientes, 3 deles sem email. Quantas linhas WHERE email LIKE '%' devolve?

5. A Ana quer os textos que contêm um sublinhado de verdade (_). Qual padrão está certo?

6. Qual é o curinga de "qualquer sequência" no GLOB?

Missão final: o Rafael ou o Roberto?

Missão: um cliente de São Paulo ligou; a atendente só entendeu que o nome começa com "R". Mostre os clientes de São Paulo cujo nome começa com R (são 2). Use LIKE no nome e mantenha o filtro da cidade.

SELECT nome, cidade, email
FROM clientes
WHERE cidade = 'São Paulo';
SELECT nome, cidade, email
FROM clientes
WHERE cidade = 'São Paulo'
  AND nome LIKE 'R%';

Resumo

  • LIKE ("parecido com") compara um texto com um padrão. O % quer dizer "qualquer coisa" (até nada); o _, "uma letra qualquer" (próxima aula).
  • 'abc%' começa com, '%abc' termina com, '%abc%' contém. Sem curinga, o padrão tem de casar com o texto inteiro.
  • No SQLite, o LIKE ignora maiúsculas só de A a Z: 'a' LIKE 'A' é 1, mas 'á' LIKE 'Á' é 0. Escreva os acentos como estão guardados.
  • NULL não combina com nenhum padrão, nem com '%', nem no NOT LIKE.
  • Para achar um % ou _ de verdade, use ESCAPE: LIKE '%!_%' ESCAPE '!'.
  • GLOB (só SQLite) usa *, ? e [0-9], e diferencia maiúsculas.
  • O padrão vai entre aspas simples; entre aspas duplas, o SQLite procura uma coluna.