按日期过滤现有查询

时间:2019-06-20 03:30:07

标签: php laravel-5 laravel-5.8

此问题尚未得到实用答案。

我将几种方法结合在一起,以获取我经常玩的游戏的一些有趣统计数据。

下面的方法将获取所有已玩游戏的总数,将一个玩家与该玩家列表匹配,然后显示总赢/亏损/平局的总和。

这很棒,而且功能正常。

但是,由于受欢迎的需求,我被要求调整查询以现在考虑游戏进行的日期。我想将其过滤到求和的最后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) . ' %'
            );
    }

任何帮助将不胜感激。


使用Arun P的答案时

$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 :(得分:0)

尝试一下-

$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为now()创建了carbon日期实例,如其documentation中所述。链接上述碳方法(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天)(包括当前日期)中创建的结果。

答案 1 :(得分:0)

我对您现有的查询做了一些更改,

$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中,checkSumID除以1000,然后将其包括在查询中。 checkSumID的where子句已更改为比较日期。

如果需要任何帮助,请尝试此评论。

答案 2 :(得分:-1)

尝试一下 struct File { var name: String//for 4 files var size: String//only for A and B var image: UIImage// only for C and D } 从UNIX时间戳返回日期/日期时间

from_unixtime()

答案 3 :(得分:-2)

尝试这个,像这样更新您的查询

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