MySQL Where
Aprenda a usar a cláusula WHERE do MySQL em Python com consultas parametrizadas, operadores de comparação, LIKE, IN, BETWEEN, verificações NULL e condições compostas.
A cláusula WHERE é a principal forma de filtrar linhas em uma instrução MySQL SELECT, UPDATE ou DELETE. Este capítulo mostra como usá-la em Python com mysql-connector-python, abrangendo filtros de condição única, operadores de comparação, LIKE, IN, BETWEEN, verificações de NULL e lógica composta AND/OR — tudo usando consultas parametrizadas para evitar injeção de SQL.
Pré-requisitos
Certifique-se de ter o seguinte configurado antes de executar os exemplos:
- Python 3.x e um servidor MySQL em execução.
mysql-connector-pythoninstalado:
pip install mysql-connector-python- Um banco de dados com uma tabela
customersjá criada — consulte MySQL Create Database e MySQL Create Table se ainda não tiver configurado isso.
Os exemplos assumem esta tabela e algumas linhas de amostra:
CREATE TABLE IF NOT EXISTS customers (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
address VARCHAR(255),
age INT
);
INSERT INTO customers (name, address, age) VALUES
('Alice', 'Oak Avenue 1', 30),
('Bob', 'Pine Street 42', 25),
('Charlie', 'Maple Road 7', 35),
('Diana', 'Oak Avenue 3', 28),
('Eve', NULL, 22);Por Que Usar Consultas Parametrizadas
Antes de qualquer exemplo de código, uma regra: nunca construa uma condição WHERE concatenando strings fornecidas pelo usuário diretamente no seu SQL. Este padrão é perigoso:
# NEVER do this — SQL injection risk
name = input("Enter name: ")
sql = "SELECT * FROM customers WHERE name = '" + name + "'"Se um usuário digitar ' OR '1'='1, a consulta retorna todas as linhas. Em vez disso, sempre passe os valores pela interface parametrizada do mysql-connector-python:
sql = "SELECT * FROM customers WHERE name = %s"
mycursor.execute(sql, (name,))O conector escapa o valor com segurança antes de ele chegar ao banco de dados. O marcador é sempre %s, independentemente do tipo de dado da coluna (inteiro, string, data etc.).
Filtrando por um Valor Exato
O caso de uso mais comum: recuperar linhas onde uma coluna é igual a um valor específico.
import mysql.connector
from mysql.connector import Error
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
sql = "SELECT * FROM customers WHERE name = %s"
val = ("Alice",)
mycursor.execute(sql, val)
results = mycursor.fetchall()
for row in results:
print(row)
except Error as e:
print(f"Error: {e}")
finally:
if mydb.is_connected():
mycursor.close()
mydb.close()Exemplo de saída:
(1, 'Alice', 'Oak Avenue 1', 30)Observe que val deve ser uma tupla mesmo quando há apenas um valor — daí a vírgula final em ("Alice",).
Operadores de Comparação
A cláusula WHERE suporta todos os operadores de comparação SQL padrão:
| Operador | Significado | Exemplo de condição |
|---|---|---|
= | Igual | age = 30 |
<> ou != | Diferente | age <> 30 |
> | Maior que | age > 25 |
>= | Maior ou igual | age >= 28 |
< | Menor que | age < 30 |
<= | Menor ou igual | age <= 30 |
Exemplo: Linhas onde a idade é maior que 28
import mysql.connector
from mysql.connector import Error
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
sql = "SELECT name, age FROM customers WHERE age > %s"
val = (28,)
mycursor.execute(sql, val)
for row in mycursor.fetchall():
print(row)
except Error as e:
print(f"Error: {e}")
finally:
if mydb.is_connected():
mycursor.close()
mydb.close()Exemplo de saída:
('Alice', 30)
('Charlie', 35)Correspondência com Curinga usando LIKE
LIKE corresponde a padrões dentro de colunas de string. Dois caracteres curinga estão disponíveis:
%— corresponde a zero ou mais caracteres._— corresponde a exatamente um caractere.
import mysql.connector
from mysql.connector import Error
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
# Find customers whose address starts with "Oak"
sql = "SELECT name, address FROM customers WHERE address LIKE %s"
val = ("Oak%",)
mycursor.execute(sql, val)
for row in mycursor.fetchall():
print(row)
except Error as e:
print(f"Error: {e}")
finally:
if mydb.is_connected():
mycursor.close()
mydb.close()Exemplo de saída:
('Alice', 'Oak Avenue 1')
('Diana', 'Oak Avenue 3')LIKE não diferencia maiúsculas de minúsculas em colunas utf8mb4 por padrão. Use LIKE BINARY se precisar de correspondência sensível a maiúsculas e minúsculas.
Correspondência de Múltiplos Valores com IN
IN verifica se o valor de uma coluna aparece em uma lista. É equivalente a encadear múltiplas condições OR, mas muito mais legível.
import mysql.connector
from mysql.connector import Error
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
names = ("Alice", "Charlie", "Eve")
# Build one %s placeholder per value
placeholders = ", ".join(["%s"] * len(names))
sql = f"SELECT name, age FROM customers WHERE name IN ({placeholders})"
mycursor.execute(sql, names)
for row in mycursor.fetchall():
print(row)
except Error as e:
print(f"Error: {e}")
finally:
if mydb.is_connected():
mycursor.close()
mydb.close()Exemplo de saída:
('Alice', 30)
('Charlie', 35)
('Eve', 22)Como o número de valores em IN pode variar em tempo de execução, o padrão acima constrói a string de marcadores dinamicamente (", ".join(["%s"] * len(names))). Isso mantém a parametrização intacta independentemente do tamanho da lista.
Filtragem por Intervalo com BETWEEN
BETWEEN seleciona linhas onde o valor de uma coluna está dentro de um intervalo inclusivo:
import mysql.connector
from mysql.connector import Error
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
sql = "SELECT name, age FROM customers WHERE age BETWEEN %s AND %s"
val = (25, 30)
mycursor.execute(sql, val)
for row in mycursor.fetchall():
print(row)
except Error as e:
print(f"Error: {e}")
finally:
if mydb.is_connected():
mycursor.close()
mydb.close()Exemplo de saída:
('Alice', 30)
('Bob', 25)
('Diana', 28)BETWEEN 25 AND 30 inclui os dois valores extremos (25 e 30). Funciona com datas e strings, bem como com números.
Verificação de Valores NULL
Um valor NULL significa que o campo não possui dados. Você não pode testar NULL com = — deve usar IS NULL ou IS NOT NULL.
import mysql.connector
from mysql.connector import Error
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
# Find customers with no address recorded
sql = "SELECT name FROM customers WHERE address IS NULL"
mycursor.execute(sql)
for row in mycursor.fetchall():
print(row)
except Error as e:
print(f"Error: {e}")
finally:
if mydb.is_connected():
mycursor.close()
mydb.close()Exemplo de saída:
('Eve',)IS NULL e IS NOT NULL não requerem parâmetros, portanto nenhum segundo argumento é passado para execute().
Condições Compostas com AND e OR
Combine múltiplas condições em uma única cláusula WHERE usando AND (todas as condições devem ser verdadeiras) e OR (pelo menos uma condição deve ser verdadeira).
Exemplo com AND
import mysql.connector
from mysql.connector import Error
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
# Customers on "Oak Avenue" who are older than 28
sql = "SELECT name, address, age FROM customers WHERE address LIKE %s AND age > %s"
val = ("Oak%", 28)
mycursor.execute(sql, val)
for row in mycursor.fetchall():
print(row)
except Error as e:
print(f"Error: {e}")
finally:
if mydb.is_connected():
mycursor.close()
mydb.close()Exemplo de saída:
('Alice', 'Oak Avenue 1', 30)Diana mora na Oak Avenue, mas tem 28 anos, então não satisfaz age > 28.
Exemplo com OR
import mysql.connector
from mysql.connector import Error
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
# Customers named Alice OR younger than 25
sql = "SELECT name, age FROM customers WHERE name = %s OR age < %s"
val = ("Alice", 25)
mycursor.execute(sql, val)
for row in mycursor.fetchall():
print(row)
except Error as e:
print(f"Error: {e}")
finally:
if mydb.is_connected():
mycursor.close()
mydb.close()Exemplo de saída:
('Alice', 30)
('Eve', 22)Use parênteses para controlar a precedência ao misturar AND e OR: (a OR b) AND c se comporta de forma diferente de a OR (b AND c).
Usando WHERE com UPDATE e DELETE
A cláusula WHERE é igualmente essencial nas instruções UPDATE e DELETE. Sem ela, a instrução afeta todas as linhas da tabela.
import mysql.connector
from mysql.connector import Error
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
# Update only Alice's address
sql = "UPDATE customers SET address = %s WHERE name = %s"
val = ("New Street 10", "Alice")
mycursor.execute(sql, val)
mydb.commit()
print(mycursor.rowcount, "row(s) updated")
except Error as e:
print(f"Error: {e}")
mydb.rollback()
finally:
if mydb.is_connected():
mycursor.close()
mydb.close()Exemplo de saída:
1 row(s) updatedSempre verifique sua condição WHERE com um SELECT primeiro antes de executar um UPDATE ou DELETE. Uma condição ausente ou errada em uma tabela de produção pode ser difícil de reverter. Consulte MySQL Update e MySQL Delete para mais detalhes.
Obtendo Uma Linha vs Todas as Linhas
Após execute(), escolha quantas linhas recuperar:
| Método | Retorna | Use quando |
|---|---|---|
fetchone() | Primeira linha correspondente (ou None) | Você espera no máximo um resultado, ex.: busca por chave primária |
fetchmany(n) | Até n linhas | Paginação ou pré-visualizações limitadas |
fetchall() | Todas as linhas correspondentes como uma lista | Conjuntos de resultados pequenos onde carregar todas as linhas de uma vez é aceitável |
mycursor.execute("SELECT * FROM customers WHERE age > %s", (25,))
# Fetch only the first result
first = mycursor.fetchone()
print(first) # (1, 'Alice', 'Oak Avenue 1', 30)Para conjuntos de resultados grandes, prefira fetchmany() em um loop ou use um cursor do lado do servidor (MySQLCursorBuffered) para evitar carregar todas as linhas na memória de uma vez.
Erros Comuns a Evitar
Usar = para verificar NULL. WHERE address = NULL nunca retorna nenhuma linha; sempre use IS NULL.
Esquecer a vírgula final em uma tupla de valor único. Escrever val = ("Alice") cria uma string, não uma tupla. Escreva val = ("Alice",).
Formatar valores em strings para SQL. F-strings e formatação com % ignoram a parametrização. Passe os valores como segundo argumento para execute().
Omitir WHERE em UPDATE ou DELETE. Sem uma cláusula WHERE, todas as linhas da tabela são afetadas.
Usar Python None onde SQL NULL é necessário. mysql-connector-python mapeia Python None para SQL NULL automaticamente, portanto mycursor.execute("UPDATE customers SET address = %s WHERE id = %s", (None, 1)) define address como NULL corretamente.
O Que Fazer a Seguir
- MySQL Order By — ordene as linhas que sua cláusula
WHEREretorna. - MySQL Limit — limite o número de linhas retornadas.
- MySQL Update — modifique linhas que correspondem a uma condição.
- MySQL Delete — remova linhas que correspondem a uma condição.
- MySQL Join — filtre por múltiplas tabelas com
WHEREcombinado com joins.