SELECT: extraindo os dados certos

BETWEEN, IN e LIKE: filtros mais curtos

22 min
O que você vai aprender
  • escrever filtros curtos com BETWEEN, IN e LIKE
  • entender que o BETWEEN inclui as duas pontas do intervalo
  • trocar longas sequências de OR por um IN (...) curto e legível
  • buscar texto por padrão com LIKE, % e _
  • distinguir o % do _ nos padrões de texto
  • buscar texto sem diferenciar maiúsculas de minúsculas com ILIKE ou LOWER(...)
  • escapar os caracteres especiais % e _ quando você precisa encontrá-los como texto comum
  • explicar por que LIKE 'abc%' pode usar um índice, enquanto LIKE '%abc' muitas vezes obriga o banco a percorrer a tabela inteira
  • perceber a armadilha do NOT IN quando a lista ou a subconsulta pode conter um NULL

Operadores de condição práticos

Os restauradores da velha Terra recompunham livros a partir de um fragmento do desenho da encadernação. Nem sempre precisavam do título exato. Às vezes bastava um indício: começa com tal letra, pertence a tal seção, está em tal faixa de datas.

O arquivista de dados trabalha de um jeito parecido.

No WHERE, nem sempre é confortável escrever um monte de condições ligadas por AND e OR. Às vezes a ideia fica mais simples com um operador curto:

price >= 1000 AND price <= 3000

pode ser escrito assim:

price BETWEEN 1000 AND 3000

E uma sequência longa como:

category = 'Книги'
OR category = 'Игрушки'
OR category = 'Аксессуары'

pode ser trocada por:

category IN ('Книги', 'Игрушки', 'Аксессуары')

E, se você precisa encontrar os itens cujo nome começa com a palavra «Café», dá para usar um padrão:

name LIKE 'Кофе%'

Nesta aula há três ferramentas principais:

  • BETWEEN a AND b — o valor cai no intervalo de a até b;
  • IN (...) — o valor está na lista;
  • LIKE 'padrão' — o texto se encaixa num padrão de texto.

Nenhum dos três operadores faz mágica. Eles só ajudam a escrever condições mais curtas e mais claras.

QUERY: Um bom filtro é como uma ordem precisa para um drone batedor: não «procure alguma coisa útil», e sim «mostre os itens destas categorias, nesta faixa, com o nome começando assim».

Um estêncil-padrão holográfico através do qual as linhas correspondentes se iluminam entre duas marcas luminosas de intervalo
Busca por modelo: o intervalo BETWEEN, a lista IN e o estêncil LIKE — o próprio arquivo encontra as correspondências.

Três modelos diferentes de busca

Esses operadores têm papéis diferentes.

O BETWEEN responde à pergunta:

O valor está entre dois limites?

Por exemplo:

price BETWEEN 1000 AND 3000

Lê-se assim:

preço de 1000 a 3000, inclusive.

O IN responde à pergunta:

O valor está neste conjunto de opções?

Por exemplo:

category IN ('Книги', 'Игрушки')

Lê-se assim:

a categoria é Livros ou Brinquedos.

O LIKE responde à pergunta:

O texto se parece com este padrão?

Por exemplo:

name LIKE 'Кофе%'

Lê-se assim:

o nome começa com "Café".

Ou seja:

OperadorQuando usarExemplo
BETWEENvocê precisa de um intervaloprice BETWEEN 1000 AND 3000
INvocê precisa de uma lista de opçõescategory IN ('Книги', 'Игрушки')
LIKEvocê precisa de um padrão de textoname LIKE 'Кофе%'

BETWEEN: um valor entre dois limites

O BETWEEN verifica se um valor está dentro de um intervalo.

Digamos que você precise encontrar os itens com preço de 1000 a 3000:

SELECT name, price
FROM products
WHERE price BETWEEN 1000 AND 3000;

É o mesmo que escrever:

SELECT name, price
FROM products
WHERE price >= 1000
  AND price <= 3000;

O detalhe principal:

O BETWEEN inclui os dois limites.

Ou seja, a condição:

price BETWEEN 1000 AND 3000

devolve os itens com preço:

  • 1000
  • 1500
  • 2999
  • 3000

O preço 1000 entra.
O preço 3000 também entra.

Se você precisa de valores estritamente maiores que 1000 e estritamente menores que 3000, o BETWEEN não serve. Nesse caso, escreva as comparações comuns:

WHERE price > 1000
  AND price < 3000
price BETWEEN 1000 AND 3000500350010003000● both bounds included: ≥ 1000 and ≤ 3000 ○ outside
BETWEEN 1000 AND 3000 inclui os dois limites: tanto 1000 quanto 3000 entram no resultado.
Vamos encontrar os itens da faixa de preço intermediária. O BETWEEN se lê quase como uma frase comum: preço entre 1000 e 3000.

Detalhes importantes do BETWEEN

1. Os limites não se invertem sozinhos

Este filtro está correto:

WHERE price BETWEEN 1000 AND 3000

Já este quase sempre devolve um resultado vazio:

WHERE price BETWEEN 3000 AND 1000

porque o banco lê isso como:

WHERE price >= 3000
  AND price <= 1000

Nenhum número comum consegue ser maior ou igual a 3000 e menor ou igual a 1000 ao mesmo tempo.

Por isso a ordem dos limites importa: primeiro o inferior, depois o superior.

2. Existe a forma inversa, NOT BETWEEN

Se você precisa encontrar os itens fora do intervalo, pode escrever:

SELECT name, price
FROM products
WHERE price NOT BETWEEN 1000 AND 3000;

Isso é parecido com:

WHERE price < 1000
   OR price > 3000

Ou seja, o item de 500 entra.
O item de 4000 entra.
O item de 1000 não entra.
O item de 3000 não entra.

Porque os limites fazem parte do próprio intervalo do BETWEEN.

3. Com datas e horários é preciso mais cuidado

O BETWEEN também funciona com datas:

WHERE created_at BETWEEN '2024-01-01' AND '2024-01-31'

Mas, se created_at não for só uma data, e sim uma data com hora, por exemplo:

2024-01-31 18:45:00

esse filtro pode acabar deixando de fora quase todo o último dia.

Por quê? Porque, para um timestamp, '2024-01-31' costuma significar o começo do dia:

2024-01-31 00:00:00

Por isso, quando o período envolve horário, costuma ser mais seguro escrever um intervalo semiaberto:

WHERE created_at >= '2024-01-01'
  AND created_at <  '2024-02-01'

Assim pegamos tudo a partir de 1º de janeiro, inclusive, e tudo até 1º de fevereiro, sem incluir 1º de fevereiro.

Para quem está começando, a regra principal é esta:

Para números, o BETWEEN é prático e claro. Para datas com hora, confira os limites com atenção redobrada.

IN: o valor está na lista

O IN é usado quando você precisa testar um valor contra várias opções possíveis.

Digamos que você precise encontrar só os itens das categorias "Livros" e "Brinquedos":

SELECT name, category, price
FROM products
WHERE category IN ('Книги', 'Игрушки');

Isso é mais curto e mais claro do que:

SELECT name, category, price
FROM products
WHERE category = 'Книги'
   OR category = 'Игрушки';

O IN se lê assim:

a categoria está na lista: Livros, Brinquedos.

O IN fica especialmente útil quando há muitas opções:

WHERE category IN ('Книги', 'Игрушки', 'Аксессуары', 'Корм', 'Домики')

Em vez de uma longa sequência de OR, sai um único filtro compacto.

Vamos selecionar só os itens das categorias que interessam. O IN substitui várias condições ligadas por OR.

Detalhes importantes do IN

1. O IN é prático para uma lista de valores exatos

O IN não procura valores parecidos. Ele verifica a correspondência exata com uma das opções.

WHERE category IN ('Книги', 'Игрушки')

Vai encontrar a categoria 'Книги'.

Mas não vai encontrar:

Книга
книги
КНИГИ
Электронные книги

porque essas já são outras strings.

2. O NOT IN exclui os valores da lista

Se você precisa tirar algumas categorias, pode escrever:

SELECT name, category, price
FROM products
WHERE category NOT IN ('Книги', 'Игрушки');

Lê-se assim:

mostre os itens cuja categoria não está na lista "Livros", "Brinquedos".

Mas o NOT IN tem uma armadilha importante com NULL. Ela vem logo abaixo, num bloco separado.

3. O IN combina bem com o BETWEEN

Por exemplo:

SELECT name, category, price
FROM products
WHERE category IN ('Книги', 'Игрушки')
  AND price BETWEEN 1000 AND 3000
ORDER BY price;

Lê-se assim:

mostre livros e brinquedos com preço de 1000 a 3000.

Esse já é um filtro completo de verdade: uma lista de categorias mais um intervalo de preço.

O arquivo seleciona pelo modelo: Livros e Brinquedos de 1000 a 3000 — uma prateleira pronta para a vitrine.

LIKE: busca por padrão de texto

O LIKE é usado quando você precisa encontrar um texto não pela correspondência exata, mas por um padrão.

Digamos que você precise encontrar os itens cujo nome começa com a palavra "Café":

SELECT name, price
FROM products
WHERE name LIKE 'Кофе%';

O sinal % significa:

qualquer quantidade de caracteres, sejam quais forem.

Inclusive nenhum caractere.

Por isso o padrão:

'Кофе%'

vai encontrar:

Кофе
Кофе молотый
Кофейная станция
Кофе для котонавтов

Mas não vai encontrar:

Большой кофе
Набор: кофе и кружка

porque o padrão exige que o texto comece por Кофе.

LIKE 'A%'AnnaAppleBarsikLuna%any numberof chars (even 0)_exactly onechar'c_t' → cat, cot · 'c%t' → cat, carrot
O estêncil LIKE: o % se estica por qualquer quantidade de caracteres (inclusive zero), e o _ ocupa exatamente uma posição.

%: qualquer quantidade de caracteres

O % é o caractere mais frequente no LIKE.

Ele significa:

aqui pode haver qualquer quantidade de caracteres.

Veja os padrões a seguir.

Começa com um texto

WHERE name LIKE 'Кофе%'

Vai encontrar os nomes que começam por Кофе.

Exemplos de correspondências:

Кофе
Кофе молотый
Кофейный набор

Termina com um texto

WHERE name LIKE '%кофе'

Vai encontrar os nomes que terminam em кофе.

Exemplos de correspondências:

Большой кофе
Капсульный кофе
Набор для кофе

Contém o texto em qualquer lugar

WHERE name LIKE '%кофе%'

Vai encontrar os nomes em que кофе aparece em qualquer posição.

Exemplos de correspondências:

кофе
Большой кофе
Набор для кофе и чая
Свежие кофейные зёрна

Já o exemplo com letra maiúscula da primeira lista não aparece aqui: o LIKE diferencia maiúsculas de minúsculas, e К e к são caracteres diferentes. Vamos falar mais sobre maiúsculas e minúsculas logo adiante nesta aula.

Em linguagem figurada:

'Кофе%'

— o texto precisa começar com essa sequência.

'%кофе'

— o texto precisa terminar com essa sequência.

'%кофе%'

— o texto precisa conter essa sequência em algum lugar.

_: exatamente um caractere

Além do %, o LIKE tem um segundo caractere especial:

_

Ele significa:

exatamente um caractere qualquer.

Por exemplo:

WHERE code LIKE 'A_1'

Servem:

AB1
AX1
A71

Mas não servem:

A1
ABCD1
AA21

Por quê?

O padrão A_1 exige:

  1. primeiro A
  2. depois exatamente um caractere qualquer
  3. depois 1

Mais um exemplo:

WHERE name LIKE 'Кот_'

Servem as strings de quatro caracteres:

Коты
Котя
Кот1

Mas não serve:

Кот
Котик

Porque o _ exige exatamente um caractere a mais.

A diferença é esta:

PadrãoO que significa
'Кот%'Кот e depois quantos caracteres você quiser
'Кот_'Кот e depois exatamente um caractere
Vamos encontrar os itens cujo nome começa com "Café". O % permite qualquer continuação depois do início indicado.

Maiúsculas e minúsculas: LIKE, ILIKE e LOWER

No PostgreSQL, o LIKE comum diferencia maiúsculas de minúsculas.

Isso quer dizer que o padrão:

WHERE name LIKE 'смарт%'

pode não encontrar esta linha:

Смарт-часы

porque с e С são caracteres diferentes.

Para buscar sem diferenciar maiúsculas de minúsculas, o PostgreSQL tem o ILIKE:

SELECT name, price
FROM products
WHERE name ILIKE 'смарт%';

O ILIKE é a variante do LIKE que ignora maiúsculas e minúsculas.

Ele vai encontrar:

смарт-часы
Смарт-часы
СМАРТ-ЧАСЫ

Mas vale lembrar: o ILIKE é uma facilidade do PostgreSQL, não uma parte universal do SQL padrão.

Uma abordagem mais portável é passar todo o texto para a mesma caixa:

SELECT name, price
FROM products
WHERE LOWER(name) LIKE 'смарт%';

Aqui o banco primeiro converte name para minúsculas e só depois compara com o padrão escrito em minúsculas.

Também dá para fazer assim:

WHERE LOWER(name) LIKE LOWER('Смарт%')

Mas, na prática, o padrão já costuma ser escrito direto em minúsculas:

WHERE LOWER(name) LIKE 'смарт%'

Como buscar os próprios caracteres % e _

O LIKE tem um problema: % e _ são caracteres especiais.

% significa qualquer quantidade de caracteres.
_ significa exatamente um caractere.

Mas às vezes você precisa encontrar o sinal de porcentagem ou o sublinhado como texto comum.

Por exemplo, imagine estes itens:

Скидка 50%
Корм 50 кг
QA_набор
QA-набор

Se você escrever:

WHERE name LIKE '50%'

isso não quer dizer "encontre o texto 50%".

Quer dizer:

encontre as linhas que começam com 50 e seguem com qualquer coisa.

Para dizer ao banco "este % é um sinal de porcentagem comum", usa-se o ESCAPE.

Por exemplo:

SELECT name
FROM products
WHERE name LIKE '%50!%%' ESCAPE '!';

Vamos destrinchar o padrão:

'%50!%%'
  • o primeiro % — qualquer começo de texto
  • 50 — caracteres comuns
  • !% — um sinal de porcentagem comum, porque ! foi definido como caractere de escape
  • o último % — qualquer continuação do texto

A cláusula:

ESCAPE '!'

diz ao SQL:

se antes de % ou de _ vier um !, trate o caractere seguinte como texto comum.

Do mesmo jeito dá para buscar o sublinhado:

SELECT name
FROM products
WHERE name LIKE 'QA!_%' ESCAPE '!';

Esse padrão encontra as linhas que começam com o texto comum QA_.

Sem escape, o padrão:

'QA_%'

significaria:

QA, depois um caractere qualquer, depois qualquer continuação.

E poderia trazer linhas a mais, como:

QA-набор
QA1набор
QA набор

QUERY: No estêncil do LIKE, os caracteres % e _ não são tinta, são furos. Se você quer encontrar o furo em si no desenho, avise antes ao arquivo que ali está um sinal comum.

O preço de um % inicial

Numa tabela pequena, a diferença quase não aparece. Mas, em milhões de linhas, padrões LIKE diferentes podem se comportar de formas bem distintas.

Compare duas condições:

WHERE name LIKE 'Кофе%'

e

WHERE name LIKE '%кофе'

A primeira condição conhece o começo do texto. O banco consegue raciocinar mais ou menos como você faria com um dicionário de papel:

Abra o dicionário nessa seção e procure ali por perto.

Essa busca por prefixo às vezes pode ser acelerada por um índice.

Já a segunda condição começa com %:

'%кофе'

Isso quer dizer:

antes dessa palavra pode vir qualquer coisa.

A correspondência pode estar em qualquer ponto do texto. Um índice comum na coluna name já não ajuda tanto, porque o banco não sabe por onde começar a procurar.

Por isso, consultas do tipo:

WHERE name LIKE '%кофе%'

costumam levar à leitura de um número enorme de linhas: o banco precisa verificar cada nome.

Uma ideia simples:

CondiçãoO que o banco sabeCostuma ser mais rápido?
LIKE 'Кофе%'o prefixo é conhecidosim, um índice pode ajudar
LIKE '%кофе'o começo é desconhecidocostuma ser lento
LIKE '%кофе%'a correspondência pode estar em qualquer lugarcostuma ser lento

No PostgreSQL existem detalhes técnicos: para acelerar um LIKE por prefixo, às vezes é preciso um índice com text_pattern_ops ou um locale adequado, e para buscar no meio do texto usam-se os índices de trigramas pg_trgm.

Mas, nesta etapa, o importante é entender a ideia em si:

Se o padrão começa com caracteres comuns, fica mais fácil para o banco procurar. Se o padrão começa com %, muitas vezes o banco precisa reler uma parte bem maior da tabela.

A propriedade de uma condição "saber usar um índice" chama-se . Vamos ver isso em detalhe no módulo sobre otimização.

Regra para a prática

Bom:

WHERE name LIKE 'Кофе%'

Cuidado:

WHERE name LIKE '%кофе%'

A primeira consulta busca a partir de um começo de texto conhecido.

A segunda procura um trecho em qualquer posição. Numa tabela grande, isso pode sair caro.

Isso não significa que LIKE '%кофе%' seja proibido. Às vezes ele é necessário. Mas, se essa busca for frequente e em uma tabela grande, aí já é caso para índices especiais ou para um mecanismo de busca à parte.

UNKNOWN nas condições de lista e a armadilha do NOT IN

Na aula anterior você já viu que o NULL produz um terceiro resultado lógico:

UNKNOWN

Isso também vale para o IN.

Enquanto a lista é escrita à mão e só tem valores comuns, tudo é simples:

WHERE category IN ('Книги', 'Игрушки')

Isso é parecido com:

WHERE category = 'Книги'
   OR category = 'Игрушки'

Já o NOT IN funciona como uma sequência de condições ligadas por AND.

Por exemplo:

WHERE category NOT IN ('Книги', 'Игрушки')

é parecido com:

WHERE category <> 'Книги'
  AND category <> 'Игрушки'

E é aqui que aparece a armadilha.

Veja:

SELECT 'нашлось'
WHERE 1 NOT IN (2, 3);

Essa consulta devolve uma linha, porque:

1 <> 2 AND 1 <> 3

é:

TRUE AND TRUE

Resultado: TRUE.

E agora:

SELECT 'нашлось'
WHERE 1 NOT IN (2, NULL);

Essa consulta não devolve linha nenhuma.

Por quê?

O NOT IN (2, NULL) se desdobra mais ou menos assim:

1 <> 2 AND 1 <> NULL

A primeira parte:

1 <> 2

TRUE.

A segunda parte:

1 <> NULL

UNKNOWN.

Resultado:

TRUE AND UNKNOWN

UNKNOWN.

E o WHERE só deixa passar o que é TRUE.

Por isso a linha não chega ao resultado.

A situação mais perigosa não é aquela em que a lista é escrita à mão. Ali o NULL está à vista.

O perigo aparece com as subconsultas:

WHERE product_id NOT IN (
    SELECT product_id
    FROM archived_products
)

Se a subconsulta devolver ao menos um NULL, o resultado pode ficar inesperadamente vazio.

Por ora, guarde o sinal de alerta:

NOT IN + um NULL possível = risco de resultado vazio.

Nos próximos módulos, quando aparecerem as subconsultas, você vai conhecer alternativas mais seguras com NOT EXISTS.

O que acontece quando o valor é NULL

BETWEEN, IN e LIKE também obedecem à lógica do NULL.

Se o valor está ausente, uma verificação comum não resulta em TRUE.

Por exemplo:

price BETWEEN 1000 AND 3000

Se price for NULL, o resultado é UNKNOWN.

category IN ('Книги', 'Игрушки')

Se category for NULL, o resultado é UNKNOWN.

name LIKE 'Кофе%'

Se name for NULL, o resultado é UNKNOWN.

E o WHERE só deixa passar o que é TRUE.

Por isso as linhas com NULL não passam sozinhas por esses filtros.

Se você precisa incluí-las, acrescente uma condição explícita:

WHERE price BETWEEN 1000 AND 3000
   OR price IS NULL

ou:

WHERE category IN ('Книги', 'Игрушки')
   OR category IS NULL

Não ache que BETWEEN, IN ou LIKE "entendem" os valores ausentes de algum jeito especial. Para o NULL, continuam sendo necessários o IS NULL e o IS NOT NULL.

Erros comuns

Erro 1. Esquecer que o BETWEEN inclui os limites

WHERE price BETWEEN 1000 AND 3000

Isso inclui tanto 1000 quanto 3000.

Se os limites não devem entrar, escreva:

WHERE price > 1000
  AND price < 3000

Erro 2. Usar BETWEEN com datas e cortar sem querer o último dia

Cuidado:

WHERE created_at BETWEEN '2024-01-01' AND '2024-01-31'

Se created_at também guarda o horário, parte dos registros de 31 de janeiro pode ficar de fora.

Costuma ser mais seguro assim:

WHERE created_at >= '2024-01-01'
  AND created_at <  '2024-02-01'

Erro 3. Escrever muitos OR em vez de IN

Dá para fazer assim:

WHERE category = 'Книги'
   OR category = 'Игрушки'
   OR category = 'Аксессуары'

Mas fica mais legível assim:

WHERE category IN ('Книги', 'Игрушки', 'Аксессуары')

Erro 4. Achar que o IN procura texto parecido

WHERE category IN ('Книги')

Não vai encontrar:

Электронные книги

porque o IN verifica a correspondência exata.

Para buscar texto parecido, use o LIKE:

WHERE category LIKE '%книги%'

Ou o ILIKE, se você quer uma busca que ignore maiúsculas e minúsculas no PostgreSQL:

WHERE category ILIKE '%книги%'

Erro 5. Confundir % e _

LIKE 'A%'

A, depois qualquer quantidade de caracteres.

LIKE 'A_'

A, depois exatamente um caractere.

Erro 6. Esquecer de escapar % e _

Se você precisa encontrar o sinal % comum, não escreva assim:

WHERE name LIKE '%50%%'

É melhor escapar de forma explícita:

WHERE name LIKE '%50!%%' ESCAPE '!'

Erro 7. Colocar % no começo do padrão e esperar que a busca seja rápida

WHERE name LIKE '%кофе%'

Uma busca dessas pode ser tranquila numa tabela pequena, mas numa tabela grande costuma sair caro.

Interview question

Pergunta de entrevista:
Em que BETWEEN 1000 AND 3000 difere de price > 1000 AND price < 3000?

Resposta forte:
O BETWEEN inclui as duas pontas. Ou seja, price BETWEEN 1000 AND 3000 equivale a price >= 1000 AND price <= 3000. Já a condição price > 1000 AND price < 3000 deixa as pontas de fora.


Pergunta de entrevista:
Quando é melhor usar IN e quando é melhor usar várias condições ligadas por OR?

Resposta forte:
Se a mesma coluna é comparada com vários valores exatos, o IN costuma se ler melhor. Por exemplo, category IN ('Книги', 'Игрушки') é mais claro que category = 'Книги' OR category = 'Игрушки'. No sentido, é a verificação «o valor está na lista».


Pergunta de entrevista:
Em que o % difere do _ no LIKE?

Resposta forte:
O % significa qualquer quantidade de caracteres quaisquer, inclusive nenhum. O _ significa exatamente um caractere qualquer. Por isso LIKE 'A%' encontra A, AB, ABC, enquanto LIKE 'A_' encontra só textos de dois caracteres que começam com A.


Pergunta de entrevista:
Do ponto de vista de desempenho, em que LIKE 'abc%' difere de LIKE '%abc'?

Resposta forte:
Em LIKE 'abc%' o prefixo do texto é conhecido. O SGBD pode, em tese, usar um índice como uma busca por intervalo num dicionário ordenado. Em LIKE '%abc' o começo do texto é desconhecido: a correspondência pode começar em qualquer ponto, então um índice comum na coluna muitas vezes não ajuda, e o banco precisa conferir muitas linhas ou a tabela inteira. Se a busca no meio do texto for frequente, no PostgreSQL costuma-se olhar para os índices de trigramas pg_trgm ou para a busca de texto completo.


Pergunta de entrevista:
Por que NOT IN pode retornar, de repente, um resultado vazio?

Resposta forte:
O NOT IN é perigoso quando a lista ou o resultado da subconsulta contém NULL. Por exemplo, 1 NOT IN (2, NULL) equivale, no sentido, a 1 <> 2 AND 1 <> NULL. A primeira parte dá TRUE, a segunda dá UNKNOWN e o total é UNKNOWN. E o WHERE só deixa passar TRUE, então a linha não volta. Se a lista for montada por uma subconsulta em que pode haver NULL, é preciso um cuidado extra.

Check yourself
Quais valores atendem à condição price BETWEEN 1000 AND 3000?
Check yourself
Como escrever de forma mais curta a condição category = 'Книги' OR category = 'Игрушки'?
Check yourself
Quais nomes a condição full_name LIKE 'А%' vai encontrar?
Check yourself
O que significa o padrão code LIKE 'A_'?
Check yourself
Por que LIKE '%кофе%' pode ser lento numa tabela grande?

QUERY: Intervalo, lista e estêncil — três jeitos rápidos de perguntar ao arquivo. O importante é lembrar onde o modelo ajuda e onde ele obriga o arquivo a reler tudo, do começo ao fim.