Komplexe WHERE-Abfragen in Laravel Eloquent: 4 Methoden mit Beispielen

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Komplexe WHERE-Abfragen in Laravel Eloquent: 4 Methoden mit Beispielen

\n\n

Stellen Sie sich vor: Sie entwickeln einen Online-Shop mit Laravel. Sie müssen alle Produkte finden, die zwischen 1000 und 5000 Euro kosten, auf Lager sind, aber nicht aus der Kategorie "Sale" stammen und nach dem 1. Januar 2024 erstellt wurden. Wie machen Sie das mit einer einzigen Abfrage, ohne die Performance zu beeinträchtigen?

\n\n

Diese Frage ist eine der häufigsten auf Stack Overflow (tausende Aufrufe!). Und das zu Recht: Die Fähigkeit, komplexe WHERE-Bedingungen in Laravel Eloquent zu erstellen, unterscheidet Anfänger von erfahrenen Entwicklern.

\n\n

In diesem Artikel zeige ich Ihnen 4 bewährte Methoden, um mehrere WHERE-Bedingungen zu erstellen. Sie erfahren, wann Sie Arrays, wann Closures verwenden, wie Sie Bedingungen gruppieren und SQL-Injection vermeiden. Los geht's!

\n\n
\n\n

1. Basis-Methode: Array von Bedingungen (für einfache AND-Verknüpfungen)

\n\n

Der einfachste Fall: Alle Bedingungen werden mit AND verknüpft. Laravel erlaubt es, ein einfaches Array an where() zu übergeben:

\n\n
<?php\n\n// Wir suchen aktive Benutzer aus Deutschland, erstellt im Jahr 2024\n$users = User::where([\n    ['status', '=', 'active'],\n    ['country', '=', 'Germany'],\n    ['created_at', '>=', '2024-01-01'],\n])->get();\n\n// SQL: SELECT * FROM users WHERE status = 'active' AND country = 'Germany' AND created_at >= '2024-01-01'
\n\n

Wann verwenden: Bei 2-5 einfachen Bedingungen mit dem Operator = oder >. Der Code ist lesbar, aber nicht flexibel.

\n\n

Nachteil: Wenn Sie AND und OR mischen müssen, ist ein Array nicht geeignet.

\n\n

2. Methodenverkettung mit where() (für dynamische Bedingungen)

\n\n

Dies ist die beliebteste Methode unter Entwicklern. Sie rufen einfach mehrmals where() hintereinander auf:

\n\n
<?php\n\n$products = Product::where('price', '>', 1000)\n    ->where('price', '<', 5000)\n    ->where('in_stock', true)\n    ->where('category_id', '!=', 5)\n    ->get();\n\n// SQL: ... WHERE price > 1000 AND price < 5000 AND in_stock = 1 AND category_id <> 5
\n\n

Trick: Sie können dies mit anderen Bedingungen kombinieren:

\n\n
<?php\n\n// "ODER"-Bedingung innerhalb der Kette\n$orders = Order::where('status', 'paid')\n    ->orWhere('status', 'shipped')\n    ->where('total', '>', 100)  // Achtung: Diese Bedingung bezieht sich auf das vorherige orWhere!\n    ->get();\n\n// SQL: ... WHERE status = 'paid' OR (status = 'shipped' AND total > 100)
\n\n

⚠️ Wichtig! Im letzten Beispiel bezieht sich WHERE total > 100 nur auf status = 'shipped'. Wenn beide Status die Bedingung total > 100 erfüllen sollen, lesen Sie den nächsten Punkt.

\n\n

3. Gruppierung von Bedingungen mit Closures (AND + OR kombiniert)

\n\n

Hier kommen wir zum leistungsstärksten Werkzeug. Wenn Sie eine Gruppe von Bedingungen in Klammern setzen müssen, verwenden Sie ein Closure innerhalb von where():

\n\n
<?php\n\n// Aufgabe: Bestellungen mit Status "paid" oder "shipped" finden,\n// aber total muss in beiden Fällen > 100 sein\n$orders = Order::where(function($query) {\n        $query->where('status', 'paid')\n              ->orWhere('status', 'shipped');\n    })\n    ->where('total', '>', 100)\n    ->get();\n\n// SQL: ... WHERE (status = 'paid' OR status = 'shipped') AND total > 100
\n\n

Jetzt sind die Bedingungen korrekt gruppiert! Sie können Closures beliebig tief verschachteln:

\n\n
<?php\n\n// Komplexer Filter für Analysen\n$data = Sale::where('date', '>=', '2024-01-01')\n    ->where(function($q) {\n        $q->where('amount', '>', 10000)\n          ->orWhere('is_vip', true);\n    })\n    ->where(function($q) {\n        $q->where('region', 'Europe')\n          ->orWhere('region', 'Asia');\n    })\n    ->get();\n\n// SQL: ... WHERE date >= '2024-01-01' AND (amount > 10000 OR is_vip = 1) AND (region = 'Europe' OR region = 'Asia')
\n\n

Profi-Tipp: Verwenden Sie aussagekräftige Variablennamen wie $query oder $q in Closures, um die Lesbarkeit zu erhöhen.

\n\n

4. whereHas für Beziehungen (komplexe Bedingungen über verknüpfte Tabellen)

\n\n

Oft müssen Sie Bedingungen nicht nur auf die aktuelle Tabelle, sondern auch auf verknüpfte Tabellen anwenden. Hier kommt whereHas ins Spiel:

\n\n
<?php\n\n// Alle Benutzer finden, die mindestens eine Bestellung über 500 Euro haben\n$users = User::whereHas('orders', function($query) {\n        $query->where('total', '>', 500);\n    })->get();\n\n// SQL: SELECT * FROM users WHERE EXISTS (SELECT 1 FROM orders WHERE orders.user_id = users.id AND total > 500)
\n\n

Erweitertes Beispiel mit mehreren Bedingungen:

\n\n
<?php\n\n// Produkte finden, die in Bestellungen aus dem Jahr 2024 mit Status "completed" vorkommen\n$products = Product::whereHas('orderItems.order', function($query) {\n        $query->where('status', 'completed')\n              ->whereYear('created_at', 2024);\n    })->get();\n\n// SQL: ... WHERE EXISTS (SELECT 1 FROM order_items ... WHERE status = 'completed' AND YEAR(created_at) = 2024)
\n\n

Alternative: whereDoesntHave für Bedingungen, die nicht zutreffen sollen:

\n\n
<?php\n\n// Benutzer ohne abgeschlossene Bestellungen\n$inactiveUsers = User::whereDoesntHave('orders', function($query) {\n        $query->where('status', 'completed');\n    })->get();
\n\n
\n\n

Zusammenfassung: Wann welche Methode?

\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
MethodeAm besten geeignet für
Array in where()Einfache AND-Bedingungen, 2-5 Stück
MethodenverkettungDynamische Bedingungen, gemischte Operatoren
Closures (Gruppierung)Komplexe Logik mit AND/OR-Kombinationen
whereHas / whereDoesntHaveBedingungen über verknüpfte Tabellen (Beziehungen)
\n\n

Bonus-Tipp: Verwenden Sie whereBetween für Bereichsabfragen und whereIn für mehrere Werte, um Ihren Code noch sauberer zu halten:

\n\n
<?php\n\n$products = Product::whereBetween('price', [1000, 5000])\n    ->whereIn('category_id', [1, 3, 7])\n    ->where('in_stock', true)\n    ->get();\n\n// SQL: ... WHERE price BETWEEN 1000 AND 5000 AND category_id IN (1, 3, 7) AND in_stock = 1
\n\n

Jetzt sind Sie bestens gerüstet, um komplexe WHERE-Abfragen in Laravel Eloquent zu meistern. Probieren Sie die Methoden in Ihrem nächsten Projekt aus und optimieren Sie Ihre Datenbankabfragen!

Blogs

Buchempfehlungen