Python MySQL Select With a Filter
In this page:
Basic WHERE Filtering
cursor.execute("SELECT * FROM customers WHERE address = %s", ("Park Lane 38",)) returns only the rows where the address column exactly matches the given value, instead of every row in the table.
Note: Always pass the comparison value through the parameterized tuple argument, never embedded directly in the SQL string, even for values that seem harmless.
Warning: Forgetting the trailing comma in a single-value tuple like ("value",) turns it into a plain string instead of a tuple, which raises a confusing error.
Example: Basic WHERE Filtering
from unittest.mock import MagicMock
conn = MagicMock()
cursor = conn.cursor()
cursor.execute("SELECT * FROM customers WHERE address = %s", ("Park Lane 38",))
print("Filtered by exact address match")
Pattern Matching with LIKE
LIKE combined with the % wildcard character enables partial text matching inside a WHERE clause -- 'Ap%' matches anything starting with Ap, '%way%' matches anything containing way anywhere, useful for search-style features.
Note: Use LIKE with leading and trailing % (like "%term%") to implement a basic case-insensitive substring search feature.
Warning: A LIKE pattern with a leading % (like "%way") cannot use a standard index efficiently, which can slow down searches significantly on very large tables.
Example: Pattern Matching with LIKE
from unittest.mock import MagicMock
conn = MagicMock()
cursor = conn.cursor()
cursor.execute("SELECT * FROM customers WHERE address LIKE %s", ("%way%",))
print("Matches any address containing 'way'")
Combining Conditions with AND / OR
Multiple conditions can be combined in a single WHERE clause using AND (all conditions must be true) or OR (at least one must be true), exactly mirroring how Python's own and/or operators combine boolean expressions.
Note: Use parentheses to group combined AND/OR conditions explicitly when mixing both in the same WHERE clause, to avoid ambiguity about which conditions group together.
Warning: MySQL evaluates AND with higher precedence than OR by default, just like Python -- an ungrouped mix of both can filter differently than intended.
Example: Combining Conditions with AND / OR
from unittest.mock import MagicMock
conn = MagicMock()
cursor = conn.cursor()
cursor.execute(
"SELECT * FROM customers WHERE city = %s AND age > %s",
("Austin", 18),
)
print("Both conditions must be true")
Filtering on NULL Values
IS NULL and IS NOT NULL are the only correct ways to filter rows based on a column having (or not having) no value at all -- a plain = comparison against NULL never returns true in SQL, even when comparing NULL to NULL itself.
Note: Remember that in SQL, NULL represents "unknown," not "empty" -- this is why standard equality comparisons against it never work as expected.
Warning: WHERE column = NULL is a silent logical bug, not a syntax error -- it simply always returns zero rows, which can be confusing to debug.
Example: Filtering on NULL Values
from unittest.mock import MagicMock
conn = MagicMock()
cursor = conn.cursor()
cursor.execute("SELECT * FROM customers WHERE address IS NULL")
print("= NULL never matches; IS NULL is required")
Why Parameterized Queries Matter
Building a WHERE clause by directly inserting user input into an SQL string -- with an f-string or % formatting -- allows an attacker to inject their own SQL logic through that input, a vulnerability called SQL injection; parameterized %s placeholders prevent this entirely by keeping data and SQL structure strictly separate.
Note: Treat every single value that comes from outside your own code (user input, an API response, a file) as untrusted, and always pass it through a parameterized placeholder, never string concatenation.
Warning: Even values that seem obviously safe, like a numeric ID from a URL, should still go through a parameterized placeholder -- consistency prevents the one exception that becomes a real vulnerability.
Example: Why Parameterized Queries Matter
from unittest.mock import MagicMock
conn = MagicMock()
cursor = conn.cursor()
user_input = "Park Lane 38"
# Safe: value is passed separately, never concatenated into the SQL string
cursor.execute("SELECT * FROM customers WHERE address = %s", (user_input,))
print("Protected against SQL injection")
- Building the WHERE condition's value directly into the SQL string with an f-string instead of a %s placeholder, opening an SQL injection vulnerability -- the single most important thing to get right here.
- Using = to compare against NULL, which never matches in SQL -- IS NULL or IS NOT NULL must be used instead.
- Forgetting that string comparisons in a WHERE clause are typically case-insensitive by default in MySQL (depending on the column's collation), which can surprise developers used to case-sensitive comparisons in Python.
- A WHERE clause filters which rows a SELECT statement returns, based on a condition.
- Always pass WHERE clause values as a separate parameterized tuple with %s placeholders, never string-formatted directly into the SQL.
- LIKE with % wildcards enables partial, pattern-based text matching inside a WHERE clause.
WHERE clause syntax is standard SQL and works identically across all mysql-connector-python versions.
Chapter Quiz — Complete all 12 topics to unlock
0/12 topics done
Complete these topics first:
- Python MySQL Get Started
- Python MySQL Create Database
- Python MySQL Create Table
- Python MySQL Insert Into Table
- Python MySQL Select From Table
- Python MySQL Select With a Filter
- Python MySQL Order By
- Python MySQL Delete Record
- Python MySQL Drop Table
- Python MySQL Update Table
- Python MySQL Limit
- Python MySQL Join