1

So i have a pivot table like the following :

match id
player id
score

And i want to query to get the number of wins/losses for a given user id. (wins based on user id with the highest score for a game)

In sql i would write this like :

SELECT user_id, score 
from match_user matchu1 
where score = (select max(score) from match_user matchu2 where matchu1.match_id = matchu2.match_id) 

How would i express this query in laravel, or is there a better method of doing this that i am missing ?

3 Answers 3

2

There are multiple ways to achieve this. The easiest and cleaniest way to me is defining a relationship with pivot.

class Match extends Model
{
    public function players()
    {
        return $this->belongsToMany(User::class, 'match_user')->withPivot('score');
    }

    public function winner()
    {
        return $this->players
            ->sortByDesc(function ($player) {
                return $player->pivot->score;
            })
            ->first();
    }
}

Then you can simply get the winner by saying:

$match->winner();
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks Kevin. I thought I was missing an elegant solution like this. How would this work for wanting to get number of wins for a user? I can call the inverse in the player model and return the games but it won't let me call ->count()
Please ask a different question. I kind of got a solution for that.
for some reason i cannot post a new question. Though, this was initially what i was trying to do - "get the number of wins/losses for a given user id".
2

This is to answer your true intention of asking this question, which is to get the number of wins for a single user, as you commented on my answer. The following the the best solution that I can think of for now:

class Match extends Model
{
    public function scopeWonBy($query, User $user)
    {
        return $query->selectRaw('matches.id, max(match_user.score) AS max_store, match_user.player_id AS player_id')
            ->join('match_user', 'matches.id', '=', 'match_user.match_id')
            ->groupBy('matches.id')
            ->having('player_id', $user->id);
    }
}

Later on, you can say:

$matches = Match::wonBy($user);
$count = Match::wonBy($user)->count();

Comments

0

I'm not going to write your query for you as I don't want to provide an untested solution but the following code example should give you a good idea of how to implement subqueries with the query builder.

$q->where('price_date', function($q) use ($start_date)
{
   $q->from('benchmarks_table_name')
    ->selectRaw('min(price_date)')
    ->where('price_date', '>=', $start_date)
    ->where('ticker', $this->ticker);
});

Comments

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.