Фильтрация существующего запроса по дате - PullRequest
5 голосов
/ 20 июня 2019

На этот вопрос еще предстоит ответить функциональным ответом.

У меня есть несколько методов, которые я собрал для забавной статистики в игре, в которую я часто играю.

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

Это здорово и функционально.

Однако из-за широкого спроса меня попросили скорректировать запрос, чтобы теперь учитывать дату, в которую игра прошла. Я хотел бы отфильтровать это до последних 30 дней суммирования. Как я могу это сделать?

Я хотел спросить, прежде чем тратить время на переписывание всего этого. Желательно, чтобы все оставалось неизменным, просто отфильтруйте по дате.

Ключ даты для базы данных: checkSumID это метка времени UNIX.

private function topPlayers() {

        $topPlayersList = array();

        $playersList = DB::table('pickup_results')
            ->select(DB::raw("playerID"),
                DB::raw("COUNT(CASE WHEN gameResult = 'Win'  THEN 1 END) AS wins"),
                DB::raw("COUNT(CASE WHEN gameResult = 'Loss' THEN 1 END) AS loss"),
                DB::raw("COUNT(CASE WHEN gameResult = 'Tie' THEN 1 END) AS tie")
            )
            ->groupBy('playerID')
            ->orderBy('wins','DESC')
            ->get();

        $i = 0;

        foreach ($playersList as $playerListData) {

            if ($playerListData->wins + $playerListData->loss + $playerListData->tie >= 25) {

                $avgPick = $this->getPlayerAvgPickCount($playerListData->playerID);

                $playerRecordID = $playerListData->playerID;

                $playerNameLookup = Players::where([
                    'player_id' => $playerListData->playerID
                ])->first();

                $playerListData->playerID = $playerNameLookup->player_name;

                $topPlayersList[$i] = array(
                    'name' => $playerNameLookup->player_name,
                    'total' => +$playerListData->wins + +$playerListData->loss + +$playerListData->tie,
                    'wins' => +$playerListData->wins,
                    'loss' => +$playerListData->loss,
                    'tie' => +$playerListData->tie,
                    'percent' => +$playerListData->loss == 0 ? 0 : round(
                            (+$playerListData->wins / (+$playerListData->wins + +$playerListData->loss) * 100),
                            2
                        ) . ' %',
                    'avg_pick' => $avgPick[0]->average,
                    'player_id' => $playerRecordID
                );

                $i++;

            }

        }

        return $this->sortArray($topPlayersList,'percent','DESC');
    }

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

Вот этот метод

private function getTotalGamesPlayed30DayWinLossTies() {

        //PickupResults::where('playerID', '=', $this->getPlayerID())->where('checkSumID', '=', Carbon::now()->subDays(30)->timestamp)->count()
        $results = PickupResults::get();

        //$results = PickupResults::where('playerID', '=', $this->getPlayerID())->get();

        $count = 0;
        $wins = 0;
        $loss = 0;
        $tie = 0;
        foreach ($results as $result) {

            if ($result->playerID === $this->playerID) {
                $timeStamp = $result->checkSumID;

                $converted = date('m/d/Y', $timeStamp / 1000);
                if (strtotime($converted) > strtotime('-30 days')) {
                    $count = $count + 1;
                    if ($result->gameResult === 'Win') {
                        $wins = $wins + 1;
                    }
                    if ($result->gameResult === 'Loss') {
                        $loss = $loss + 1;
                    }
                    if ($result->gameResult === 'Tie') {
                        $tie = $tie + 1;
                    }

                }
            }

        }

        return
            array(
                'total' => $count,
                'wins' => $wins,
                'loss' => $loss,
                'tie' => $tie,
                'percent' => $loss == 0 ? 0 : round(($wins / ( $wins + $loss) * 100 ),2) . ' %'
            );
    }

Любая помощь будет принята с благодарностью.


При использовании ответа Аруна Р

$playersList = DB::table('pickup_results')
    ->select(DB::raw("playerID"),
        DB::raw("COUNT(CASE WHEN gameResult = 'Win'  THEN 1 END) AS wins"),
        DB::raw("COUNT(CASE WHEN gameResult = 'Loss' THEN 1 END) AS loss"),
        DB::raw("COUNT(CASE WHEN gameResult = 'Tie' THEN 1 END) AS tie"))
    ->where('checksumID','<',$now)->where('checksumID','>',$thirty_days_ahead)
    ->groupBy('playerID')
    ->orderBy('wins', 'DESC')
    ->get();

Возвращает 0 результатов. Это неверно; Я пытаюсь собрать все игры, в которые игрок играл только за последние 30 дней. Ничего больше, ни меньше.

Вы можете посетить http://www.Krayvok.com/t1 и просмотреть страницу статистики для рабочего примера.

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

Ответы [ 4 ]

0 голосов
/ 07 июля 2019

Я внес некоторые изменения в ваш существующий запрос,

$timestamp_from = date('Y-m-d', strtotime('-30 days'));

$playersList = DB::table('pickup_results')
    ->select(DB::raw("playerID"),
        DB::raw("COUNT(CASE WHEN gameResult = 'Win'  THEN 1 END) AS wins"),
        DB::raw("COUNT(CASE WHEN gameResult = 'Loss' THEN 1 END) AS loss"),
        DB::raw("COUNT(CASE WHEN gameResult = 'Tie' THEN 1 END) AS tie")
    )
    ->where(DB::raw("DATE((checkSumID/1000)) >= '{$timestamp_from}'"))
    ->groupBy('playerID')
    ->orderBy('wins','DESC')
    ->get();

В вашем методе getTotalGamesPlayed30DayWinLossTies есть деление на 1000 для checkSumID, и я включил его в запрос. Предложение where для checkSumID было изменено для сравнения дат.

Попробуйте этот комментарий, если вам нужна помощь.

0 голосов
/ 01 июля 2019

Попробуйте, обновите ваш запрос следующим образом

 $thirty_days_ahead = date('Y-m-d H:i:s', strtotime("-30 days"));
    $now = date('Y-m-d H:i:s', strtotime("0 days"));


    $results = DB::table('pickup_results')
    ->select(DB::raw("playerID"),
    DB::raw("COUNT(CASE WHEN gameResult = 'Win'  THEN 1 END) AS wins"),
    DB::raw("COUNT(CASE WHEN gameResult = 'Loss' THEN 1 END) AS loss"),
    DB::raw("COUNT(CASE WHEN gameResult = 'Tie' THEN 1 END) AS tie"))
    ->where('checksumID','<',$now)->where('checksumID','>',$thirty_days_ahead)
    ->groupBy('playerID')
    ->orderBy('wins', 'DESC')
    ->get();
0 голосов
/ 06 июля 2019

Попробуйте это -

$playersList = DB::table('pickup_results')
        ->select(DB::raw("playerID"),
            DB::raw("COUNT(CASE WHEN gameResult = 'Win' AND checkSumID > '".now()->subDays(30)->toDateString()."' THEN 1 END) AS wins"),
            DB::raw("COUNT(CASE WHEN gameResult = 'Loss' AND checkSumID > '".now()->subDays(30)->toDateString()."' THEN 1 END) AS loss"),
            DB::raw("COUNT(CASE WHEN gameResult = 'Tie' AND checkSumID > '".now()->subDays(30)->toDateString()."' THEN 1 END) AS tie")
        )
        ->groupBy('playerID')
        ->orderBy('wins','DESC')
        ->get();

Laravel создает экземпляр даты carbon для now(), как указано в его документации . Цепочка указанных углеродных методов ( carbon docs ) возвращает дату 30 дней назад.

Все операторы SELECT будут преобразованы в нечто подобное (если текущая дата '2019-07-06') -

COUNT(CASE WHEN gameResult = 'Win' AND checkSumID > '2019-06-06' THEN 1 END) AS wins

Будет подсчитан результат, который был создан после '2019-06-06' (за последние 30 дней) , включая текущую дату.

0 голосов
/ 20 июня 2019

попробуйте это from_unixtime() возвращает дату / дату / время из метки времени Unix

$playersList = DB::table('pickup_results')
        ->select(DB::raw("playerID"),
            DB::raw("COUNT(CASE WHEN gameResult = 'Win'  THEN 1 END) AS wins"),
            DB::raw("COUNT(CASE WHEN gameResult = 'Loss' THEN 1 END) AS loss"),
            DB::raw("COUNT(CASE WHEN gameResult = 'Tie' THEN 1 END) AS tie")
        )
        ->where(DB::raw("from_unixtime(checkSumID) > date_sub(now(), interval 30 day)"))
        ->groupBy('playerID')
        ->orderBy('wins','DESC')
        ->get();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...