🇯🇵 日本語 | 🇺🇸 English | 🇪🇸 Español | 🇵🇹 Português | 🇹🇭 ไทย | 🇨🇳 中文

【Cláusula LIKE do SQL】Domine a busca por correspondência parcial! Como usar os curingas `%` e `_`

A funcionalidade de busca é essencial em um site, não é mesmo? Inúmeras vezes, queremos encontrar dados que não correspondem exatamente, mas parcialmente, como "quero encontrar livros que contenham a palavra 'SQL'" ou "quero listar usuários cujo nome começa com 'Silva'". Usando o sinal de igual (=) na cláusula WHERE, podemos encontrar dados com correspondência exata, mas como podemos fazer "buscas aproximadas" ou "buscas por correspondência parcial"?

A resposta para isso é a cláusula LIKE do SQL. A cláusula LIKE, quando combinada com a cláusula WHERE, permite extrair dados com base em correspondências parciais de strings. E o que eleva drasticamente essa capacidade de busca são os símbolos especiais chamados curingas. Assim como o coringa em um baralho de cartas, esses símbolos podem se transformar em qualquer caractere. Ao dominar seu uso, sua busca de dados se tornará muito mais livre e poderosa.

Neste artigo, vamos explicar detalhadamente, com código que você pode copiar e colar, desde o uso básico da cláusula LIKE, a diferença entre os dois principais curingas (% e _), até pontos importantes para o uso prático. Vamos lá, explore o mundo da cláusula LIKE para se tornar um mestre das buscas!


Preparação: Vamos preparar os dados dos livros para a busca

Para experimentar a busca por correspondência parcial, primeiro vamos preparar os dados que serão o alvo da busca. Desta vez, criaremos uma tabela simples de books para gerenciar uma lista de livros. Para permitir a experimentação com várias variações de busca, registraremos intencionalmente livros com títulos semelhantes e títulos que contêm símbolos especiais.

-- Se a tabela books existir, exclua-a (para poder testar repetidamente)
DROP TABLE IF EXISTS books;

-- Cria uma nova tabela books
CREATE TABLE books (
  id INTEGER PRIMARY KEY,
  title TEXT NOT NULL,
  author TEXT NOT NULL,
  price INTEGER
);

-- Insere os dados iniciais
INSERT INTO books (id, title, author, price) VALUES
(1, 'Começando com SQL', 'Taro Yamada', 2500),
(2, 'Análise de Dados SQL na Prática!', 'Ichiro Suzuki', 3200),
(3, 'O Manual de Web Design', 'Hanako Sato', 2800),
(4, 'Introdução divertida ao SQL', 'Taro Yamada', 2200),
(5, 'Guia de Criação de Sites', 'Jiro Sato', 3000),
(6, 'Técnicas de Marketing com 120% de Crescimento', 'Minoru Tanaka', 1800),
(7, 'Continuação: Começando com SQL', 'Taro Yamada', 2600);

Com isso, estamos prontos para tentar buscar com várias palavras-chave.


Curinga ①: `%` (Percentual) - Qualquer string de 0 ou mais caracteres

O % é o curinga mais utilizado com a cláusula LIKE. Ele significa "qualquer string de 0 ou mais caracteres, sem restrição de comprimento ou tipo". Pense nele como uma carta curinga que vale para tudo.

Correspondência inicial: Encontrando dados que "começam com..."

Usando no formato 'string_de_busca%', você pode encontrar dados que "começam com a string especificada".

Cenário: "Quero encontrar livros cujo título começa com 'SQL'"

SELECT * FROM books WHERE title LIKE 'SQL%';

Resultado da execução:

id | title             | author      | price
---|-------------------|-------------|-------
1  | Começando com SQL | Taro Yamada | 2500

Encontramos o livro de ID 1, 'Começando com SQL'. 'Introdução divertida ao SQL' e 'Análise de Dados SQL na Prática!' não foram incluídos nos resultados porque não começam com "SQL".


Correspondência final: Encontrando dados que "terminam com..."

Usando no formato '%string_de_busca', você pode encontrar dados que "terminam com a string especificada".

Cenário: "Quero encontrar livros cujo autor termina com 'Taro'"

SELECT * FROM books WHERE author LIKE '%Taro';

Resultado da execução:

id | title                       | author      | price
---|-----------------------------|-------------|-------
1  | Começando com SQL           | Taro Yamada | 2500
4  | Introdução divertida ao SQL   | Taro Yamada | 2200
7  | Continuação: Começando com SQL | Taro Yamada | 2600

Todos os livros do "Taro Yamada" foram listados.


Correspondência parcial (intermediária): Encontrando dados que "contêm..."

Este é o uso mais versátil. Ao envolver a palavra-chave de busca com %, como em '%string_de_busca%', você pode encontrar todos os dados que "contêm a string especificada em qualquer lugar".

Cenário: "Quero encontrar todos os livros que contenham a palavra 'SQL' no título"

SELECT * FROM books WHERE title LIKE '%SQL%';

Resultado da execução:

id | title                       | author        | price
---|-----------------------------|---------------|-------
1  | Começando com SQL           | Taro Yamada   | 2500
2  | Análise de Dados SQL na Prática!| Ichiro Suzuki | 3200
4  | Introdução divertida ao SQL   | Taro Yamada   | 2200
7  | Continuação: Começando com SQL | Taro Yamada   | 2600

Desta vez, não importa onde "SQL" apareça no título, todos foram incluídos nos resultados da busca. Nos bastidores das funções de busca de sites, consultas como essa são usadas com frequência.


Curinga ②: `_` (Sublinhado) - Qualquer caractere único

O outro curinga importante é o _ (sublinhado). Enquanto o % era um "vale-tudo" para 0 ou mais caracteres, o _ significa "exatamente um caractere qualquer". A grande diferença é que o número de caracteres é fixo em apenas um.

Isso é útil para buscas detalhadas, como, por exemplo, distinguir entre "site" e "saito".

Cenário: "Quero encontrar autores cujo sobrenome é 'Sato' e o nome tem dois caracteres (ex: Sato Hanako, Sato Jiro)"

-- Padrão que corresponde a 'Sato ' seguido por dois caracteres quaisquer
SELECT * FROM books WHERE author LIKE 'Sato __';

Resultado da execução:

id | title                     | author     | price
---|---------------------------|------------|-------
3  | O Manual de Web Design    | Hanako Sato| 2800
5  | Guia de Criação de Sites    | Jiro Sato  | 3000

Ao usar _ duas vezes, especificamos "dois caracteres quaisquer" e conseguimos encontrar tanto "Hanako Sato" quanto "Jiro Sato". Se usássemos LIKE 'Sato _', apenas pessoas com um nome de um caractere (se existissem) seriam encontradas.


Aplicação: Quando você quer buscar por `%` ou `_` como caracteres literais (cláusula `ESCAPE`)

Agora, uma pergunta um pouco mais capciosa. O que você faria se quisesse "encontrar livros que contêm a string '120%' no título"?

Se você simplesmente escrever WHERE title LIKE '%120%%', o primeiro % e o último % serão interpretados como curingas, e a busca não funcionará como o esperado. É para casos como este, onde você quer buscar pelo próprio caractere curinga como um "caractere literal", que a cláusula ESCAPE entra em cena.

Com a cláusula ESCAPE, você pode definir seu próprio "caractere de escape", que diz "o curinga logo após este caractere deve ter seu significado especial desativado (escapado)".

-- Define '!' como o caractere de escape
SELECT * FROM books WHERE title LIKE '%120!%%' ESCAPE '!';

Nesta consulta, com ESCAPE '!', definimos ! como o caractere de escape. Isso faz com que a parte !% signifique "este não é um curinga, mas sim o caractere '%'". Como resultado, apenas o livro de ID 6, 'Técnicas de Marketing com 120% de Crescimento', é encontrado corretamente.

Caracteres como !, # ou \ (barra invertida) são frequentemente usados como caracteres de escape.


【Área Experimental】Execute SQL no seu navegador e teste a busca por correspondência parcial!

Hora de transformar conhecimento em habilidade! Copie todo o código HTML abaixo, salve-o em um arquivo como sql_like_test.html e abra-o no seu navegador. Um ambiente de execução de SQL exclusivo para você será iniciado, com a tabela books usada neste artigo já preparada.

Tente mudar a posição de % e _, altere as palavras-chave e veja como os resultados da busca mudam. O caminho para se tornar um mestre das buscas está na tentativa e erro!

<!DOCTYPE html>
<html lang="pt">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Ambiente de Execução Online da Cláusula LIKE do SQL</title>
  <style>
    body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; line-height: 1.7; color: #333; max-width: 800px; margin: 2rem auto; padding: 0 1rem; }
    h1 { color: #3498db; }
    textarea { width: 100%; height: 180px; font-family: "SF Mono", "Consolas", monospace; font-size: 16px; padding: 12px; border: 1px solid #ccc; border-radius: 6px; box-sizing: border-box; margin-bottom: 1rem; }
    button { background-color: #3498db; color: white; border: none; padding: 12px 22px; font-size: 16px; border-radius: 6px; cursor: pointer; transition: background-color 0.2s; }
    button:hover { background-color: #2980b9; }
    button:disabled { background-color: #bdc3c7; cursor: not-allowed; }
    #result-container { margin-top: 2rem; border: 1px solid #ddd; padding: 1rem; border-radius: 6px; background: #fdfdfd; min-height: 50px; }
    #error-message { color: #e74c3c; font-weight: bold; }
    table { border-collapse: collapse; width: 100%; margin-top: 1rem; }
    th, td { border: 1px solid #ddd; padding: 10px; text-align: left; }
    th { background-color: #f2f2f2; }
    tr:nth-child(even) { background-color: #f9f9f9; }
  </style>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.10.3/sql-wasm.js"></script>
</head>
<body>

  <h1>Vamos testar o SQL!</h1>
  <p>Digite sua instrução SQL na área de texto abaixo e pressione o botão "Executar". Tente buscar com várias palavras-chave!</p>

  <textarea id="sql-input">-- Vamos encontrar livros que contenham "Web" no título
SELECT * FROM books WHERE title LIKE '%Web%';
  </textarea>
  
  <button id="execute-btn">Executar</button>
  
  <div id="result-container">
    <p id="error-message"></p>
    <div id="result-output"></div>
  </div>

  <script>
    const sqlInput = document.getElementById('sql-input');
    const executeBtn = document.getElementById('execute-btn');
    const errorMsg = document.getElementById('error-message');
    const resultOutput = document.getElementById('result-output');

    let db;

    async function initDb() {
      executeBtn.disabled = true;
      executeBtn.textContent = 'Preparando o BD...';
      try {
        const SQL = await initSqlJs({
          locateFile: file => `https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.10.3/${file}`
        });
        db = new SQL.Database();
        
        const setupSql = `
          DROP TABLE IF EXISTS books;
          CREATE TABLE books (
            id INTEGER PRIMARY KEY,
            title TEXT NOT NULL,
            author TEXT NOT NULL,
            price INTEGER
          );
          INSERT INTO books (id, title, author, price) VALUES
          (1, 'Começando com SQL', 'Taro Yamada', 2500),
          (2, 'Análise de Dados SQL na Prática!', 'Ichiro Suzuki', 3200),
          (3, 'O Manual de Web Design', 'Hanako Sato', 2800),
          (4, 'Introdução divertida ao SQL', 'Taro Yamada', 2200),
          (5, 'Guia de Criação de Sites', 'Jiro Sato', 3000),
          (6, 'Técnicas de Marketing com 120% de Crescimento', 'Minoru Tanaka', 1800),
          (7, 'Continuação: Começando com SQL', 'Taro Yamada', 2600);
        `;
        db.run(setupSql);
        
        executeBtn.disabled = false;
        executeBtn.textContent = 'Executar';
        resultOutput.innerHTML = '<p>Pronto! Sinta-se à vontade para testar qualquer SQL.</p>';

      } catch (err) {
        errorMsg.textContent = 'Falha ao inicializar o banco de dados: ' + err.message;
        console.error(err);
      }
    }

    function executeSql() {
      if (!db) return;
      
      const sql = sqlInput.value;
      errorMsg.textContent = '';
      resultOutput.innerHTML = '';

      try {
        const results = db.exec(sql);
        if (results.length === 0) {
          resultOutput.innerHTML = '<p>A consulta foi bem-sucedida, mas nenhum conjunto de resultados foi retornado.</p>';
          return;
        }
        
        results.forEach(result => {
          const table = document.createElement('table');
          const thead = document.createElement('thead');
          const tbody = document.createElement('tbody');
          
          const headerRow = document.createElement('tr');
          result.columns.forEach(colName => {
            const th = document.createElement('th');
            th.textContent = colName;
            headerRow.appendChild(th);
          });
          thead.appendChild(headerRow);
          
          result.values.forEach(row => {
            const bodyRow = document.createElement('tr');
            row.forEach(cellValue => {
              const td = document.createElement('td');
              td.textContent = cellValue === null ? 'NULL' : cellValue;
              bodyRow.appendChild(td);
            });
            tbody.appendChild(bodyRow);
          });
          
          table.appendChild(thead);
          table.appendChild(tbody);
          resultOutput.appendChild(table);
        });

      } catch (err) {
        errorMsg.textContent = 'Erro de SQL: ' + err.message;
        console.error(err);
      }
    }

    executeBtn.addEventListener('click', executeSql);
    
    initDb();
  </script>
</body>
</html>

Pontos de atenção: Desempenho e distinção entre maiúsculas e minúsculas (Case Sensitivity)

A cláusula LIKE é extremamente útil, mas há alguns pontos a serem observados ao usá-la em um ambiente de produção.

Para buscas de alta velocidade em grandes volumes de dados de texto, é mais comum usar funcionalidades mais avançadas, como a "Busca de Texto Completo (Full-Text Search)", em vez da cláusula LIKE. Depois de dominar a cláusula LIKE, um bom próximo passo seria aprender sobre a busca de texto completo.


Resumo

Desta vez, aprendemos sobre a cláusula LIKE para realizar buscas por correspondência parcial em SQL, com foco em seus poderosos ajudantes, os curingas.

Dominar a cláusula LIKE é uma habilidade essencial para fornecer uma funcionalidade de busca amigável ao usuário. Por favor, use a área experimental deste artigo para testar vários padrões e se familiarizar com a sensação da busca por correspondência parcial. Suas habilidades em SQL certamente subiram de nível!