简体   繁体   中英

Laravel 5.8 Eloquent doesn't work as intended despite the raw dumped query from it works

I'm having an issue with Eloquent querying things different than if I'm using the raw query, despite it returning the exact same raw query when I dump it with toSql()

This should return 3 rows, but instead returns 40

$equipment = Equipment::where(["class_id" => $this->classId, "class_id2" => $this->classId, "class_id3" => $this->classId])
                    ->orWhere(["class_id" => 0, "class_id2" => 0, "class_id3" => 0])
                    ->where("type_id", ">", "7")
                    ->get();

This returns 3 and works as expected

$equipment = \DB::table("equipment")
                        ->whereRaw("(`class_id` = ".$this->classId." and `class_id2` = ".$this->classId." and `class_id3` = ".$this->classId.") 
                                    or (`class_id` = ".$this->classId." or `class_id2` = ".$this->classId." or `class_id3` = ".$this->classId.") 
                                    and `type_id` > 7")
                        ->get();

The exact raw query Eloquent dumps is this:

select * 
from `equipment` 
where (`class_id` = 14 and `class_id2` = 14 and `class_id3` = 14) 
   or (`class_id` = 14 or `class_id2` = 14 or `class_id3` = 14) 
  and `type_id` > 7

When running this in Navicat, it also returns 3 rows.

What am I missing here?

You should be more explicit about your groups of conditions, which you can do by using an anonymous function as the argument to the first where() , with the argument of $query (which will be the querybuilder object itself).

$classID = 14;
$equipment = Equipment::where(function($query) use ($classID) {
                                  $query->where('class_id', $classID)
                                        ->orWhere('class_id2', $classID)
                                        ->orWhere('class_id3', $classID);
                        })->where("type_id", ">", "7")
                        ->get();

The query you currently have doesn't make that much sense, as the OR conditions will always be true when the AND condition is, so we can remove the first part of it, thereby simplifying the query.

You can debug your queries by using toSql() instead of get() , which will print the final SQL string. Had you done that here, you'd see that the conditions becomes something like WHERE .. OR .. AND .. , instead of WHERE (.. OR ..) AND .. .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM