I really don't get it, help me understand.
I'm writing an app which among other things calculates a NFL team "mark" (a mark is Win/Lose/Tie, sorry I don't know the word in English for that), so I have a "Marca" attribute in the Team model, looks like this:
public function getMarcaAttribute() {
...
}
Queries are very easy, first I get the number of games where the team is playing as local and calculate wins, loses and ties, for example, this one is for wins:
$gan += Juego::where('local', $this->id)
->where('score_local', '>', 'score_visitante')
->get()->count();
Then I do the same with games as visitor, but inverting comparison signs, of course.
Now, lets take a look at game Seattle (38) at Atlanta (25), if I do in the database
SELECT COUNT(*) FROM juegos WHERE local='atl' AND score_local > score_visitante;
Of course, it returns 0.
In the ORM, the generated query is:
array (
'query' => 'select * from `juegos` where `local` = ? and `score_local` > ? and `score_local` is not null',
'bindings' =>
array (
0 => 'atl',
1 => 'score_visitante',
),
'time' => 0.89,
),
The thing is returning a 1. I even replaced the ->count()->get()
for a ->get()
and do a foreach
over the results:
$gan = Juego::where('local', $this->id)
->where('score_local', '>', 'score_visitante')
->get();
Log::info('Ganados');
foreach ($gan as $g) {
Log::info("$g->score_local > $g->score_visitante");
}
The thing is returning a line where it says "25 > 38"
I really don't understand what happens here. Any idea?
You can achieve this using whereRaw
:
$gan = Juego::where('local', $this->id)
->whereRaw('score_local > score_visitante')
->get();
Or as suggested in comments, whereColumn
:
$gan = Juego::where('local', $this->id)
->whereColumn('score_local', '>' , 'score_visitante')
->get();
@lagbox had it figured out in the comments. The problem is that by using prepared statements with bindings the term score_visitante
is not been treated as a column name rather than a string.
There are several ways to solve it:
whereColumn
:$gan += Juego::where('local', $this->id)
->whereColumn('score_local', '>', 'score_visitante')
->count();
whereRaw
:$gan += Juego::where('local', $this->id)
->whereRaw('score_local > score_visitante')
->count();
DB::raw
:$gan += Juego::where('local', $this->id)
->where('score_local', '>', \DB::raw('score_visitante'))
->count();
Note: You also do not need the
->get()
before the->count()
. You can instruct the database to do the counting. This is particularly useful when the expected result is a large dataset with many rows, by returning just a number instead of potentially thousands or even millions of rows you are preserving your network resources.
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.