W3docs

MySQL Where

Aprende a usar la cláusula WHERE de MySQL en Python con consultas parametrizadas, operadores de comparación, LIKE, IN, BETWEEN, comprobaciones NULL y condiciones compuestas.

La cláusula WHERE es la forma principal de filtrar filas en una instrucción MySQL SELECT, UPDATE o DELETE. Este capítulo muestra cómo usarla desde Python con mysql-connector-python, abarcando filtros de una sola condición, operadores de comparación, LIKE, IN, BETWEEN, comprobaciones de NULL y lógica compuesta con AND/OR — todo utilizando consultas parametrizadas para prevenir la inyección SQL.

Requisitos previos

Asegúrate de tener lo siguiente antes de ejecutar los ejemplos:

  • Python 3.x y un servidor MySQL en ejecución.
  • mysql-connector-python instalado:
pip install mysql-connector-python

Los ejemplos asumen esta tabla y algunas filas de muestra:

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 qué usar consultas parametrizadas

Antes de cualquier ejemplo de código, una regla: nunca construyas una condición WHERE concatenando cadenas suministradas por el usuario directamente en tu SQL. Este patrón es peligroso:

# NEVER do this — SQL injection risk
name = input("Enter name: ")
sql = "SELECT * FROM customers WHERE name = '" + name + "'"

Si un usuario introduce ' OR '1'='1, la consulta devuelve todas las filas. En su lugar, siempre pasa los valores a través de la interfaz parametrizada de mysql-connector-python:

sql = "SELECT * FROM customers WHERE name = %s"
mycursor.execute(sql, (name,))

El conector escapa el valor de forma segura antes de que llegue a la base de datos. El marcador de posición siempre es %s independientemente del tipo de dato de la columna (entero, string, fecha, etc.).

Filtrar por un valor exacto

El caso de uso más común: recuperar filas donde una columna es igual a un 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()

Salida de ejemplo:

(1, 'Alice', 'Oak Avenue 1', 30)

Ten en cuenta que val debe ser una tupla incluso cuando solo hay un valor — de ahí la coma final en ("Alice",).

Operadores de comparación

La cláusula WHERE admite todos los operadores de comparación estándar de SQL:

OperadorSignificadoCondición de ejemplo
=Igualage = 30
<> o !=Distintoage <> 30
>Mayor queage > 25
>=Mayor o igual queage >= 28
<Menor queage < 30
<=Menor o igual queage <= 30

Ejemplo: Filas donde age es mayor 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()

Salida de ejemplo:

('Alice', 30)
('Charlie', 35)

Coincidencia de patrones con LIKE

LIKE hace coincidir patrones dentro de columnas de tipo string. Hay dos caracteres comodín disponibles:

  • % — coincide con cero o más caracteres.
  • _ — coincide con exactamente un carácter.
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()

Salida de ejemplo:

('Alice', 'Oak Avenue 1')
('Diana', 'Oak Avenue 3')

LIKE no distingue mayúsculas de minúsculas en columnas utf8mb4 por defecto. Usa LIKE BINARY si necesitas una coincidencia sensible a mayúsculas y minúsculas.

Coincidencia de múltiples valores con IN

IN comprueba si el valor de una columna aparece en una lista. Es equivalente a encadenar múltiples condiciones OR, pero mucho más legible.

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()

Salida de ejemplo:

('Alice', 30)
('Charlie', 35)
('Eve', 22)

Dado que el número de valores en IN puede variar en tiempo de ejecución, el patrón anterior construye la cadena de marcadores de posición de forma dinámica (", ".join(["%s"] * len(names))). Esto mantiene la parametrización intacta independientemente de la longitud de la lista.

Filtrado por rango con BETWEEN

BETWEEN selecciona filas donde el valor de una columna cae dentro de un rango 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()

Salida de ejemplo:

('Alice', 30)
('Bob', 25)
('Diana', 28)

BETWEEN 25 AND 30 incluye ambos valores extremos (25 y 30). Funciona con fechas y strings además de con números.

Verificar valores NULL

Un valor NULL significa que el campo no tiene datos. No puedes comprobar NULL con = — debes usar IS NULL o 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()

Salida de ejemplo:

('Eve',)

IS NULL e IS NOT NULL no toman parámetros, por lo que no se pasa un segundo argumento a execute().

Condiciones compuestas con AND y OR

Combina múltiples condiciones en una cláusula WHERE usando AND (todas las condiciones deben ser verdaderas) y OR (al menos una condición debe ser verdadera).

Ejemplo con 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()

Salida de ejemplo:

('Alice', 'Oak Avenue 1', 30)

Diana vive en Oak Avenue pero tiene 28 años, por lo que no satisface age > 28.

Ejemplo con 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()

Salida de ejemplo:

('Alice', 30)
('Eve', 22)

Usa paréntesis para controlar la precedencia al mezclar AND y OR: (a OR b) AND c se comporta de manera diferente a a OR (b AND c).

Usar WHERE con UPDATE y DELETE

La cláusula WHERE es igualmente crítica en las instrucciones UPDATE y DELETE. Sin ella, la instrucción afecta a todas las filas de la tabla.

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()

Salida de ejemplo:

1 row(s) updated

Siempre verifica tu condición WHERE con un SELECT primero antes de ejecutar un UPDATE o DELETE. Una condición incorrecta o ausente en una tabla de producción puede ser difícil de revertir. Consulta MySQL Update y MySQL Delete para más detalles.

Obtener una fila vs todas las filas

Tras execute(), elige cuántas filas recuperar:

MétodoDevuelveÚsalo cuando
fetchone()Primera fila coincidente (o None)Esperas como máximo un resultado, p. ej. búsqueda por clave primaria
fetchmany(n)Hasta n filasPaginación o previsualizaciones limitadas
fetchall()Todas las filas coincidentes como una listaConjuntos de resultados pequeños donde cargar todas las filas a la vez es viable
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, prefiere fetchmany() en un bucle o usa un cursor del lado del servidor (MySQLCursorBuffered) para evitar cargar todas las filas en memoria de una vez.

Errores comunes que debes evitar

Usar = para comprobar NULL. WHERE address = NULL nunca devuelve ninguna fila; siempre usa IS NULL.

Olvidar la coma final en una tupla de un solo valor. Escribir val = ("Alice") crea un string, no una tupla. Escribe val = ("Alice",).

Formatear valores como strings en el SQL. Los f-strings y el formato con % omiten la parametrización. Pasa los valores como segundo argumento a execute().

Omitir WHERE en UPDATE o DELETE. Sin una cláusula WHERE, se ven afectadas todas las filas de la tabla.

Usar Python None donde se necesita SQL NULL. mysql-connector-python mapea automáticamente Python None a SQL NULL, por lo que mycursor.execute("UPDATE customers SET address = %s WHERE id = %s", (None, 1)) establece address como NULL correctamente.

Qué hacer a continuación

  • MySQL Order By — ordena las filas que devuelve tu cláusula WHERE.
  • MySQL Limit — limita el número de filas devueltas.
  • MySQL Update — modifica las filas que cumplen una condición.
  • MySQL Delete — elimina las filas que cumplen una condición.
  • MySQL Join — filtra en múltiples tablas con WHERE combinado con joins.
Was this page helpful?