重构Laravel查询

时间:2019-01-22 06:34:39

标签: laravel laravel-5 laravel-5.7

我有一个已建立的查询,我试图了解如何通过一个查询就能达到相同的目的。我对Laravel和学习是相当陌生的。无论如何,有人可以帮助我了解我如何实现自己的追求吗?

$activePlayerRoster = array();

$pickupGames = DB::table('pickup_games')
  ->where('pickupDate', '>=', Carbon::now()->subDays(30)->format('m/d/Y'))
  ->orderBy('pickupDate', 'ASC')
  ->get();

foreach ($pickupGames as $games) {

  foreach(DB::table('pickup_results')
            ->where('pickupRecordLocatorID', $games->recordLocatorID)
            ->get() as $activePlayers) {

    $activePlayerRoster[] = $activePlayers->playerID;
    $unique = array_unique($activePlayerRoster);

  }

}

$activePlayerList = array();

foreach($unique as $playerID) {

  $playerinfo = DB::table('players')
                  ->select('player_name')
                  ->where('player_id', $playerID)
                  ->first();
  $activePlayerList[] = $playerinfo;

}

return $activePlayerList;

pickup_games checkSumID 挑个日子 开始时间 时间结束 gameDuration 获奖团队 recordLocatorID PickupID

1546329808471 2019/01/01 上午08:03 上午08:53 50分钟 2 f47ac0fc775cb5793-0a8a0-ad4789d4 216

pickup_results

id checkSumID 玩家ID 球队 gameResult pickOrder PickupRecordLocatorID

1 1535074728532 425336395712954388 1个 失利 0 be3532dbb7fee8bde-2213c-5c5ce710

2 个答案:

答案 0 :(得分:1)

首先,您应该尝试编写SQL查询,然后将其转换为Laravel的数据库代码。

如果性能对您而言并不重要,则可以通过以下查询来完成:

SELECT DISTINCT players.player_name FROM pickup_results
LEFT JOIN players ON players.player_id = pickup_results.playerID
WHERE EXISTS (
  SELECT 1 FROM pickup_games
  WHERE pickupDate >= DATE_FORMAT(SUBDATE(NOW(), INTERVAL 30 DAY), '%m/%d/%Y')
    AND pickup_results.pickupRecordLocatorID = recordLocatorID
)

在这里,我假设您知道此日期比较在做什么,因为它对我来说很奇怪。

现在,让我们将其转换为Laravel的代码:

DB::table('pickup_results')
  ->select('players.player_name')->distinct()
  ->leftJoin('players', 'players.player_id', '=', 'pickup_results.playerID')
  ->whereExists(function ($query) {
    $query->select(DB::raw(1))
          ->from('pickup_games')
          ->where('pickupDate', '>=', Carbon::now()->subDays(30)->format('m/d/Y'))
          ->whereRaw('pickup_results.pickupRecordLocatorID = recordLocatorID'); 
  })
  ->get();

答案 1 :(得分:0)

基本上,我会将查询简化为SQL变体,以直接获取其核心。 查询的本质是

select `x` FROM foo WHERE id IN (
  select distinct bar.id from bar join baz on bar.id = baz.id);

这可以用口才解释为:

$thirtyDaysAgo = Carbon::now()->subDays(30)->format('m/d/Y');

$playerIds = DB::table('pickup_games')
  ->select('pickup_games.player_id')
  ->join(
      'pickup_results',
      'pickup_results.pickupRecordLocatorID',
      'pickup_games.recordLocatorID')
  ->where('pickupDate', '>=', $thirtyDaysAgo)
  ->orderBy('pickupDate', 'ASC')
  ->distinct('pickup_games.player_id');


$activePlayers = DB::table('players')
      ->select('player_name')
      ->whereIn('player_id', $playerIds);

//>>>$activePlayers->toSql();
//select "player_name" from "players" where "player_id" in (
//  select distinct * from "pickup_games" 
//  inner join "pickup_results" 
//    on "pickup_results"."pickupRecordLocatorID" = "pickup_games"."recordLocatorID" 
//  where "pickupDate" >= ? order by "pickupDate" asc
//)

从结果查询中,最好将联接重构为pickup_gamespickup_results的Eloquent模型之间的关系。这将有助于进一步简化$playerIds