【问题标题】:Filtering existing query by date按日期过滤现有查询
【发布时间】:2019-11-02 20:06:01
【问题描述】:

这还需要一个实用的答案来回答。

我整理了一些方法来统计我经常玩的游戏的一些有趣的统计数据。

以下方法将计算所有已玩游戏的总数,将玩家与玩家列表匹配,然后显示总赢/输/平局的总和。

这很棒,而且很实用。

但是,由于大众的需求,我被要求调整查询,以便现在将游戏开始的日期考虑在内。我想将其过滤到最后 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 天内玩过游戏的玩家。

【问题讨论】:

  • 为什么不添加 where 子句并将时间戳与 date_sub(now(),间隔 30 天)进行比较。这将为您提供最近 30 天的结果
  • @MekjkrhG 我该怎么做?我试着在它上面做一个地方,但由于我的计数,它给了我一个错误。我无法通过查询:/
  • 显示你尝试的更新查询
  • @Kray 为了过滤掉过去 30 天,您需要有一个包含数据的日期列 - 在 checkSumID 列中吗? (如果是这样,它的名字很奇怪)——或者,最好是,你能显示pickup_results 表的表结构吗?
  • 在您的工作示例中,您在 PHP 中将时间戳转换为日期时执行 $timeStamp / 1000。我相信您也应该能够在 checkSumID 上进行相同的划分,然后在其他示例之一中将其转换为 unix 时间以进行调整。即对于 MekjkrhG 的回答,我认为您可以将一行更改为修复它-&gt;where(DB::raw("from_unixtime(checkSumID / 1000) &gt; date_sub(now(), interval 30 day)"))

标签: php laravel-5 laravel-5.8


【解决方案1】:

试试这个 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();

【讨论】:

  • 不,不会改变查询结果。
  • nope :'(。它并没有改变查询的任何内容。想知道这是否与 PlayerID 被分组有关?或者列 checkSumID 没有被抓取?
  • 您是否在删除组后尝试过?不必抓取校验和 ID 来执行 where 子句
  • 我需要对 playerID 进行分组以显示播放器的单数计数。您可以在Krayvok.com/t1 选择“排行榜”查看此查询结果。
  • 关于做什么的任何想法@MekjkrhG
【解决方案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();

【讨论】:

  • 关于做什么的任何想法@Arun P
  • @kray 这将生成一个等于“select playerID, COUNT(CASE WHEN gameResult = 'Win' THEN 1 END) AS 获胜, COUNT(CASE WHEN gameResult = 'Loss' THEN 1 END) 的查询作为损失,计数(当 gameResult = 'Tie' THEN 1 END 时的情况)作为来自 pickup_results 的平局,其中 created_at created_at > 2019-06-01 10:10 :44 group by playerID order by wins desc" 尝试在您的数据库上执行,它返回空的原因可能是因为过去 30 天内没有条目
  • 我将用我所拥有的和它在做什么来更新我的 OP。
【解决方案3】:

试试这个 -

$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 &gt; '2019-06-06' THEN 1 END) AS wins

这将计算 “2019-06-06”(过去 30 天)包括当前日期之后创建的结果。

【讨论】:

    【解决方案4】:

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

    $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 子句已更改为比较日期。

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

    【讨论】:

      猜你喜欢
      • 2013-08-16
      • 2016-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-01
      • 2013-11-04
      • 2018-05-27
      • 1970-01-01
      相关资源
      最近更新 更多