W3docs

MySQL Where

Lerne, wie du die MySQL-WHERE-Klausel in Python mit parametrisierten Abfragen, Vergleichsoperatoren, LIKE, IN, BETWEEN, NULL-Prüfungen und zusammengesetzten Bedingungen verwendest.

Die WHERE-Klausel ist der primäre Weg, um Zeilen in einer MySQL-SELECT-, UPDATE- oder DELETE-Anweisung zu filtern. Dieses Kapitel zeigt, wie du sie in Python mit mysql-connector-python verwendest — mit einfachen Bedingungsfiltern, Vergleichsoperatoren, LIKE, IN, BETWEEN, NULL-Prüfungen und zusammengesetzter AND/OR-Logik — alles mit parametrisierten Abfragen zum Schutz vor SQL-Injection.

Voraussetzungen

Stelle sicher, dass die folgenden Dinge vorhanden sind, bevor du die Beispiele ausführst:

  • Python 3.x und ein laufender MySQL-Server.
  • mysql-connector-python installiert:
pip install mysql-connector-python

Die Beispiele setzen diese Tabelle und einige Beispielzeilen voraus:

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

Warum parametrisierte Abfragen verwenden

Vor den Code-Beispielen gilt eine Regel: Niemals eine WHERE-Bedingung durch direkte Verkettung von Benutzer-Eingaben in SQL aufbauen. Dieses Muster ist gefährlich:

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

Wenn ein Benutzer ' OR '1'='1 eingibt, gibt die Abfrage jede Zeile zurück. Übergib stattdessen Werte immer über die parametrisierte Schnittstelle von mysql-connector-python:

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

Der Connector escaped den Wert sicher, bevor er die Datenbank erreicht. Der Platzhalter ist immer %s, unabhängig vom Datentyp der Spalte (Integer, string, Datum usw.).

Nach einem genauen Wert filtern

Der häufigste Anwendungsfall: Zeilen abrufen, bei denen eine Spalte einem bestimmten Wert entspricht.

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

Beispielausgabe:

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

Beachte, dass val ein Tupel sein muss, auch wenn es nur einen Wert gibt — daher das abschließende Komma in ("Alice",).

Vergleichsoperatoren

Die WHERE-Klausel unterstützt alle Standard-SQL-Vergleichsoperatoren:

OperatorBedeutungBeispielbedingung
=Gleichage = 30
<> oder !=Ungleichage <> 30
>Größer alsage > 25
>=Größer als oder gleichage >= 28
<Kleiner alsage < 30
<=Kleiner als oder gleichage <= 30

Beispiel: Zeilen, bei denen das Alter größer als 28 ist

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

Beispielausgabe:

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

Musterabgleich mit LIKE

LIKE gleicht Muster in string-Spalten ab. Zwei Platzhalterzeichen sind verfügbar:

  • % — entspricht null oder mehr Zeichen.
  • _ — entspricht genau einem Zeichen.
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()

Beispielausgabe:

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

LIKE unterscheidet standardmäßig nicht zwischen Groß- und Kleinschreibung bei utf8mb4-Spalten. Verwende LIKE BINARY, wenn du Groß-/Kleinschreibung beachten möchtest.

Mehrere Werte mit IN abgleichen

IN prüft, ob ein Spaltenwert in einer Liste vorkommt. Es entspricht der Verknüpfung mehrerer OR-Bedingungen, ist aber deutlich lesbarer.

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

Beispielausgabe:

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

Da die Anzahl der IN-Werte zur Laufzeit variieren kann, erstellt das obige Muster den Platzhalter-string dynamisch (", ".join(["%s"] * len(names))). So bleibt die Parametrisierung unabhängig von der Listenlänge erhalten.

Bereichsfilterung mit BETWEEN

BETWEEN wählt Zeilen aus, bei denen ein Spaltenwert in einem einschließenden Bereich liegt:

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

Beispielausgabe:

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

BETWEEN 25 AND 30 schließt beide Grenzwerte ein (25 und 30). Es funktioniert auch mit Datumsangaben und strings, nicht nur mit Zahlen.

NULL-Werte prüfen

Ein NULL-Wert bedeutet, dass das Feld keine Daten enthält. Du kannst NULL nicht mit = prüfen — du musst IS NULL oder IS NOT NULL verwenden.

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

Beispielausgabe:

('Eve',)

IS NULL und IS NOT NULL benötigen keine Parameter, daher wird kein zweites Argument an execute() übergeben.

Zusammengesetzte Bedingungen mit AND und OR

Kombiniere mehrere Bedingungen in einer WHERE-Klausel mit AND (alle Bedingungen müssen wahr sein) und OR (mindestens eine Bedingung muss wahr sein).

AND-Beispiel

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

Beispielausgabe:

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

Diana wohnt zwar auf der Oak Avenue, ist aber 28 Jahre alt und erfüllt daher age > 28 nicht.

OR-Beispiel

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

Beispielausgabe:

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

Verwende Klammern zur Steuerung der Auswertungsreihenfolge, wenn du AND und OR kombinierst: (a OR b) AND c verhält sich anders als a OR (b AND c).

WHERE mit UPDATE und DELETE verwenden

Die WHERE-Klausel ist bei UPDATE- und DELETE-Anweisungen genauso wichtig. Ohne sie betrifft die Anweisung jede Zeile in der Tabelle.

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

Beispielausgabe:

1 row(s) updated

Überprüfe deine WHERE-Bedingung immer zuerst mit einem SELECT, bevor du ein UPDATE oder DELETE ausführst. Eine fehlende oder falsche Bedingung auf einer Produktionstabelle kann schwer rückgängig zu machen sein. Weitere Details findest du unter MySQL Update und MySQL Delete.

Eine Zeile oder alle Zeilen abrufen

Nach execute() wähle, wie viele Zeilen abgerufen werden sollen:

MethodeGibt zurückVerwendung
fetchone()Erste übereinstimmende Zeile (oder None)Wenn höchstens ein Ergebnis erwartet wird, z. B. Suche nach Primärschlüssel
fetchmany(n)Bis zu n ZeilenSeitenweise Ausgabe oder begrenzte Vorschauen
fetchall()Alle übereinstimmenden Zeilen als ListeKleine Ergebnismengen, bei denen das gleichzeitige Laden aller Zeilen in Ordnung ist
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)

Bei großen Ergebnismengen bevorzuge fetchmany() in einer Schleife oder verwende einen serverseitigen Cursor (MySQLCursorBuffered), um zu vermeiden, dass alle Zeilen auf einmal in den Speicher geladen werden.

Häufige Fehler vermeiden

= für NULL-Prüfungen verwenden. WHERE address = NULL gibt niemals Zeilen zurück; verwende immer IS NULL.

Das abschließende Komma bei einem Einzelwert-Tupel vergessen. val = ("Alice") erzeugt einen string, kein Tupel. Schreibe val = ("Alice",).

Werte per string-Formatierung in SQL einfügen. F-strings und %-Formatierung umgehen die Parametrisierung. Übergib Werte als zweites Argument an execute().

WHERE bei UPDATE oder DELETE weglassen. Ohne WHERE-Klausel wird jede Zeile in der Tabelle betroffen.

Python None verwenden, wo SQL NULL benötigt wird. mysql-connector-python wandelt Python None automatisch in SQL NULL um, sodass mycursor.execute("UPDATE customers SET address = %s WHERE id = %s", (None, 1)) address korrekt auf NULL setzt.

Nächste Schritte

  • MySQL Order By — sortiere die Zeilen, die deine WHERE-Klausel zurückgibt.
  • MySQL Limit — begrenze die Anzahl der zurückgegebenen Zeilen.
  • MySQL Update — ändere Zeilen, die einer Bedingung entsprechen.
  • MySQL Delete — lösche Zeilen, die einer Bedingung entsprechen.
  • MySQL Join — filtere über mehrere Tabellen mit WHERE kombiniert mit Joins.
Was this page helpful?