MySQL запрос к красноречию - PullRequest
0 голосов
/ 13 июля 2020

Я создаю счетчик баллов, подробнее см. Вопрос как отслеживать прирост баллов в mysql.

В этом вопросе я спросил, как получить данные c данные из моей базы данных, я получил отличный ответ, который возвращает правильные данные, однако теперь мне нужно добавить это в laravel.

Я надеялся просто использовать whereRaw (), но это вызвало много ошибок, и, скорее всего, это не лучшее решение.

пока что я установил связь hasMany между Player и SkillScores

class Player extends Model
{
   
    public function scores()
    {
        return $this->hasMany(SkillScores::class);
    }
    
}

Я добавил черту scopeWithskills () для поиска имя навыка:

class SkillScores extends Model
{
    public function scopeWithSkills(Builder $query)
    {
        $query->leftJoinSub(
            'select * FROM skills',
            'skills',
            'skills.id',
            'skill_scores.skill_id'
        );
    }
}

Я отправляю это в свое представление в PlayerController:

class PlayerController extends Controller
{
    public function index()
    {
        return view('player', [
            'players' => auth()->user()->players()
        ]);
    }

    public function show(Player $player)
    {
        return view('player.show', [
            'player' => $player,
            'scores' => $player->scores()->withSkills()->get()
        ]);
    }
}

Какие еще отношения мне нужно настроить, чтобы выполнить запрос ниже?

WITH cte AS (
SELECT id, player_id, skill_id,
       FIRST_VALUE(score) OVER (PARTITION BY player_id, skill_id ORDER BY created_at DESC) score, 
       FIRST_VALUE(score) OVER (PARTITION BY player_id, skill_id ORDER BY created_at DESC) - FIRST_VALUE(score) OVER (PARTITION BY player_id, skill_id ORDER BY created_at ASC) gain,
       ROW_NUMBER() OVER (PARTITION BY player_id, skill_id ORDER BY created_at DESC) rn
FROM skill_scores
WHERE created_at BETWEEN @current_date - INTERVAL @interval DAY AND @current_date
)
SELECT cte.player_id, skills.name, cte.score, cte.gain
FROM cte
JOIN skills ON skills.id = cte.skill_id
WHERE rn = 1
ORDER BY player_id, name;

EDIT: -

Теперь мне удалось заставить это работать, используя DB::select() вместо whereRaw(), но не могу не думать, что должен быть лучший способ добиться этого с отношения: -

public function gains($interval = 1)
{        
    return DB::select("WITH cte AS (
        SELECT id, player_id, skill_id,
               FIRST_VALUE(score) OVER (PARTITION BY player_id, skill_id ORDER BY created_at DESC) score, 
               FIRST_VALUE(score) OVER (PARTITION BY player_id, skill_id ORDER BY created_at DESC) - FIRST_VALUE(score) OVER (PARTITION BY player_id, skill_id ORDER BY created_at ASC) gain,
               ROW_NUMBER() OVER (PARTITION BY player_id, skill_id ORDER BY created_at DESC) rn
        FROM skill_scores2
        WHERE created_at BETWEEN now() - INTERVAL '$interval' DAY  AND now() AND player_id = '$this->id'
        )
        SELECT cte.player_id, skills.name, cte.score, cte.gain
        FROM cte
        JOIN skills ON skills.id = cte.skill_id
        WHERE rn = 1
        ORDER BY player_id, name");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...