MySQL: Filtragem avançada e consultas com expressões…

Última atualização: 2026-08-26

Quando a filtragem básica não é suficiente, a filtragem avançada permite identificar dados específicos.

Esta aula oferece uma explicação detalhada sobre combinações condicionais complexas e expressões regulares.

100%
graph TB
    A[WHERE Combinations of Conditions] --> B[AND Logic and]
    A --> C[OR Logical OR]
    A --> D[NOT Negate]
    B --> E[All conditions are met simultaneously]
    C --> F[Meets any one of the conditions]
    A --> G[IN List Matching]
    A --> H[BETWEEN Scope]
    A --> I[LIKE Wildcard]
    A --> J[REGEXP Regular]
    A --> K[EXISTS Subquery]

1. O que você vai aprender


2. Uma história real sobre um recurso de busca

(1) Problema: Resultados de pesquisa imprecisos

Um usuário pesquisa por “john” e solicita uma correspondência para:

O simples LIKE '%john%' só pode corresponder a um cenário.

(2) A solução com REGEXP

SQL
SELECT * FROM users 
WHERE first_name REGEXP '^john|john$|john' 
   OR email REGEXP 'john';

3. ANÁLISE APROFUNDADA DE AND/OR

▶ Exemplo: Combinações complexas de condições

SQL
-- Search: Engineering or Sales department, and salary > 5000
SELECT * FROM employees 
WHERE (department = 'Engineering' OR department = 'Sales')
  AND salary > 5000;

-- Search: Salary 5000-8000, not HR department
SELECT * FROM employees 
WHERE salary BETWEEN 5000 AND 8000
  AND department != 'HR';

-- Search: Hired after 2024, or salary > 10000
SELECT * FROM employees 
WHERE hire_date >= '2024-01-01' OR salary > 10000;
▶ Experimente

4. DENTRO/FORA

▶ Exemplo: Consulta de lista

SQL
-- IN Search
SELECT * FROM products WHERE category_id IN (1, 3, 5, 7);

-- NOT IN Search
SELECT * FROM products WHERE category_id NOT IN (2, 4, 6);

-- Subquery IN
SELECT * FROM employees 
WHERE department_id IN (SELECT id FROM departments WHERE location = 'Beijing');

-- NOT EXISTS replacement for NOT IN (Better performance)
SELECT * FROM customers c
WHERE NOT EXISTS (
    SELECT 1 FROM orders o WHERE o.customer_id = c.id
);
▶ Experimente

5. BETWEEN avançado

▶ Exemplo: Consulta por intervalo

SQL
-- Value Range
SELECT * FROM products WHERE price BETWEEN 100 AND 500;

-- Date Range
SELECT * FROM orders WHERE order_date BETWEEN '2026-01-01' AND '2026-06-30';

-- String Range
SELECT * FROM employees WHERE last_name BETWEEN 'A' AND 'M';

-- NOT BETWEEN
SELECT * FROM products WHERE price NOT BETWEEN 100 AND 500;
▶ Experimente

6. O caractere curinga LIKE

▶ Exemplo: Correspondência aproximada

SQL
-- % Match any number of characters (including 0)
SELECT * FROM users WHERE name LIKE 'J%';        -- Starts with J
SELECT * FROM users WHERE name LIKE '%son';      -- Ends with son
SELECT * FROM users WHERE name LIKE '%john%';    -- Contains john

-- _ Matches exactly one character
SELECT * FROM users WHERE name LIKE 'J_hn';      -- J_hn (John, Johan)

-- Used in combination
SELECT * FROM users WHERE email LIKE '%@gmail.com';

-- ESCAPE escaping special characters
SELECT * FROM files WHERE name LIKE '%\_%' ESCAPE '\\';  -- Contains _
SELECT * FROM files WHERE name LIKE '%%' ESCAPE '\\';    -- Contains %
▶ Experimente

7. REGEXP: Expressões regulares

(1) Metacaracteres comuns em expressões regulares

Metacaractere Descrição Exemplo
^ Início '^John' — Começa com John
$ Fim 'son$' — Termina com “filho”
. Qualquer caractere 'J.hn' — John, Johan
[...] Conjunto de caracteres '[abc]' — um dos seguintes: a/b/c
[^...] Excluir conjunto de caracteres [^abc] — Não é a/b/c
* 0 vezes ou mais 'ab*' — a, ab, abb
+ uma vez ou mais 'ab+' — a, ab
? 0 vezes ou 1 vez 'ab?' — a, ab
{n} exatamente n vezes 'a{3}' — aaa
{n,m} n a m vezes 'a{2,4}' — aa~aaaa
| OU 'cat|dog' — gato ou cachorro

▶ Exemplo: Consulta REGEXP

SQL
-- Starts with J or j
SELECT * FROM users WHERE first_name REGEXP '^[Jj]';

-- Contains numbers
SELECT * FROM users WHERE username REGEXP '[0-9]';

-- Email format validation (Simple)
SELECT * FROM users WHERE email REGEXP '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$';

-- Mobile phone number format (Mainland China)
SELECT * FROM users WHERE phone REGEXP '^1[3-9][0-9]{9}$';

-- Contains CJK characters
SELECT * FROM users WHERE name REGEXP '[\\u4e00-\\u9fff]';
▶ Experimente

▶ Exemplo: REGEXP x LIKE

SQL
-- LIKE matches must be at the beginning and end only
SELECT * FROM users WHERE name LIKE '%john%';  -- Contains john

-- REGEXP allows for precise control
SELECT * FROM users WHERE name REGEXP '^john$'; -- Exactly equal to john (Case-insensitive)
SELECT * FROM users WHERE name REGEXP 'john|jane'; -- john or jane
SELECT * FROM users WHERE name REGEXP '^[A-Z]'; -- Starts with a capital letter
▶ Experimente

8. Subconsultas EXISTS

▶ Exemplo: Como usar EXISTS

SQL
-- Query Customers with Orders
SELECT * FROM customers c
WHERE EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.id);

-- Query Customers with No Orders
SELECT * FROM customers c
WHERE NOT EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.id);
▶ Experimente

❓ Perguntas Frequentes

P: Uma consulta LIKE '%keyword%' pode usar um índice? R: Se o prefixo contiver %, ela não poderá usar um índice e realizará uma varredura completa da tabela. Para conjuntos de dados grandes, considere usar um índice de texto completo (FULLTEXT).

P: O que é mais rápido, REGEXP ou LIKE? R: O LIKE costuma ser mais rápido (pode usar índices). O REGEXP é mais flexível, mas não pode usar índices (suportado parcialmente no MySQL 8.0).

P: O que tem melhor desempenho, IN ou OR? R: Ambos apresentam desempenho semelhante quando há poucos dados. Quando a lista IN é longa, o MySQL a otimiza para uma busca binária ordenada, que é mais rápida do que OR.

P: Existe uma armadilha com NULL ao usar NOT IN? R: Sim. NOT IN (1, 2, NULL) sempre retorna NULL porque uma comparação envolvendo NULL resulta em NULL. Use NOT EXISTS em vez disso.


📖 Resumo


📝 Exercícios

  1. Questão básica (Dificuldade: ⭐): Use uma consulta LIKE para encontrar usuários cujos endereços de e-mail contenham “@gmail.com” e cujos nomes de usuário comecem com “J”.

  2. Problema avançado (Dificuldade ⭐⭐): Use REGEXP para identificar números de celular da China continental (que começam com 1, cujo segundo dígito é um número entre 3 e 9 e que têm um total de 11 dígitos).

  3. Questão de desafio (Dificuldade: ⭐⭐⭐): Compare as diferenças nos resultados das consultas entre NOT IN e NOT EXISTS quando há valores NULL.

Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%