Laravel - построитель запросов с подзапросом - PullRequest
1 голос
/ 12 февраля 2020

Итак, у меня есть сводная таблица, подобная следующей:

match id
player id
score

И я хочу запросить, чтобы получить количество выигрышей / проигрышей для данного идентификатора пользователя. (выигрывает на основе идентификатора пользователя с наибольшим счетом за игру)

В sql я бы написал так:

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

Как бы я express запрос в laravel или есть лучший способ сделать это, что мне не хватает?

Ответы [ 3 ]

2 голосов
/ 12 февраля 2020

Есть несколько способов добиться этого. Самый простой и понятный способ для меня - определить отношения с пивотом.

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();
    }
}

Тогда вы можете просто получить победителя, сказав:

$match->winner();
2 голосов
/ 13 февраля 2020

Это ответ на ваше истинное намерение задать этот вопрос, а именно получить количество побед для одного пользователя, как вы прокомментировали мой ответ. Следующее лучшее решение, которое я могу придумать на данный момент:

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);
    }
}

Позже вы можете сказать:

$matches = Match::wonBy($user);
$count = Match::wonBy($user)->count();
0 голосов
/ 12 февраля 2020

Я не собираюсь писать ваш запрос для вас, поскольку я не хочу предоставлять непроверенное решение, но следующий пример кода должен дать вам хорошее представление о том, как реализовать подзапросы с помощью построителя запросов.

$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);
});

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...