2017-04-10 7 views
0

In den letzten zwei Stunden habe ich mit einer MySQL-Abfrage zu kämpfen, die mit dem Laravel Query Builder erstellt wurde, aber ich verstehe einfach nicht, warum ein Parameter ignoriert wird.Laravel Query Builder: Unerwarteter Ausgang

Die Abfrage, die aus dem Abfrage-Generator kommt, ist die folgende:

select * from `deals` where 
(
    ( 
     `created_at` <= '2017-04-10 09:44:07' 
     and `valid_until` >= '2017-04-10 09:44:07' 
    ) or (
     `created_at` <= '2017-04-10 09:44:07' 
     and `valid_until` <= '2017-04-10 09:44:07' 
     and `autodelete` = '2' 
    ) or (
     `created_at` <= '2017-04-10 09:44:07' 
     and `valid_until` <= '2017-04-10 09:44:07' 
     and `autodelete` = '0' 
    ) or (
     `created_at` <= '2017-04-10 09:44:07' 
     and `valid_until` is null 
    ) 
    and `category_id` != '1' 
) and `deals`.`deleted_at` is null 
order by `order_date` desc, `created_at` desc 
limit 20 
offset 0 

Der Teil, der ignoriert wird die Filterung des category_id ist. Elemente mit der category_id 1 sollten ausgeschlossen werden, sie werden jedoch nicht ausgeschlossen. Und ich verstehe nicht warum.

Jetzt habe ich herausgefunden, dass, wenn ich diesen Teil außerhalb der Klammern verschieben, es funktioniert. Das einzige Problem ist: Ich füge diese Klammern nicht zur Abfrage hinzu, es scheint, dass Laravel das automatisch macht, weil ich weiche Löschungen verwende.

Dies ist der Code, den ich für die Erstellung der Abfrage:

 $query = Deal::query() 
     ->where(function ($query) { 
      // Active with an end date 
      $query->where('created_at', '<=', date("Y-m-d H:i:s")) 
      ->where('valid_until', '>=', date("Y-m-d H:i:s")); 
     }) 
     ->orwhere(function ($query) { 
      // Ended, but with possibility to upload a receipt 
      $query->where('created_at', '<=', date("Y-m-d H:i:s")) 
      ->where('valid_until', '<=', date("Y-m-d H:i:s")) 
      ->where('autodelete', 2); 
     }) 
     ->orwhere(function ($query) { 
      // Ended, but keep it online 
      $query->where('created_at', '<=', date("Y-m-d H:i:s")) 
      ->where('valid_until', '<=', date("Y-m-d H:i:s")) 
      ->where('autodelete', 0); 
     }) 
     ->orwhere(function ($query) { 
      // No end date 
      $query->where('created_at', '<=', date("Y-m-d H:i:s")) 
      ->where('valid_until', null); 
     }); 

// Filter categories 
if(!empty($deselectedCategories)) 
{ 
    foreach($deselectedCategories as $key => $val) 
    { 
     $query->where('category_id', '!=', $val); 
    } 
} 

$deals = $query->orderBy('order_date', 'desc')->orderBy('created_at', 'desc')->paginate($resultsPerPage); 

ich etwas mit Blick werden muss, und ich hoffe, jemand kann mir helfen. Vielen Dank im Voraus!

Antwort

0

nehmen bitte einen Blick auf Ihre Parameter Gruppierung https://laravel.com/docs/5.4/queries#parameter-grouping

ich die Abfrage neu strukturiert

  1. die entfernt und category_id! = {Val} verwenden whereNotIn
  2. umgruppiert die Abfrage

    $query = Deal::where(function 
         ($query){ 
          $query->where(function ($query) { 
                // Active with an end date 
           $query->where('created_at', '<=', date("Y-m-d H:i:s")) 
           ->where('valid_until', '>=', date("Y-m-d H:i:s")); 
          }) 
          ->orwhere(function ($query) { 
           // Ended, but with possibility to upload a receipt 
           $query->where('created_at', '<=', date("Y-m-d H:i:s")) 
           ->where('valid_until', '<=', date("Y-m-d H:i:s")) 
           ->where('autodelete', 2); 
          }) 
          ->orwhere(function ($query) { 
                // Ended, but keep it online 
           $query->where('created_at', '<=', date("Y-m-d H:i:s")) 
           ->where('valid_until', '<=', date("Y-m-d H:i:s")) 
           ->where('autodelete', 0); 
          }) 
          ->orwhere(function ($query) { 
                // No end date 
           $query->where('created_at', '<=', date("Y-m-d H:i:s")) 
           ->where('valid_until', null); 
          }); 
         }); 
    
         if (!empty($deselectedCategories)) { 
          $catList =array(); 
          foreach ($deselectedCategories as $key => $val) { 
           $catList[] = $val; 
          } 
         $query->whereNotIn('category_id', $catList); 
        } 
    $query->whereNull('deleted_at'); 
    $deals = $query->orderBy('order_date', 'desc')->orderBy('created_at', 'desc')->paginate($resultsPerPage); 
    
+0

Vielen Dank sehr viel für deine Mühe: das sieht viel sauberer aus. Aber leider ist das Ergebnis immer noch das gleiche. Die category_id wird von MySQL immer noch ignoriert. Im obigen Beispiel werden Elemente mit der Kategorie "ID 1" weiterhin in die Ausgabe eingeschlossen. –

+0

Haben Sie einige Beispieldatenquelle zu versuchen – kwaseth

+0

Die Abfrage, die aus Ihrer Version kommt, ist dies: https://pastebin.com/xwsasXC2 Ich verstehe nicht warum, aber es funktioniert, wenn die Ausgabe wie folgt ist: https : //pastebin.com/nrj4FKBs Mit dem Abfrage-Generator ist es mir nicht möglich, diese Abfrage zu erstellen. Es bleibt zwischen den Klammern. Und ich würde gerne verstehen, warum die erste Version nicht funktioniert, weil sie meiner Meinung nach richtig aussieht. Die MySQL-Tabelle, die verwendet wird, ist nur eine einfache Tabelle ohne erweiterte Einstellungen. –