0

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?

1 Answer 1

1

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 ...

Sign up to request clarification or add additional context in comments.

6 Comments

I did debug my query with toSql(), but your function seem to give syntax error, unexpected '}'
Forgot a colon at the end of orWhere(), that should be fixed now.
For some reason it's still not returning the correct rows. I'm still looking at about 40 rows instead of 3...
Alright, let's take a step back here. Can you create a DB Fiddle (for example at sqlfiddle.com), with the data you have - and which rows you expect to get back? My guess is that the orWhere() part will trigger on 37 more rows than intended, but without seeing the actual data and which rows you expect, its hard to say.
Alright, so how do you get the class ID of 14? We can also simplify the query quite a bit.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.