Рефакторинг Laravel Query - PullRequest
       0

Рефакторинг Laravel Query

0 голосов
/ 22 января 2019

У меня есть запрос, который я построил, и я пытаюсь понять, как я могу достичь того же, но с помощью одного запроса.Я довольно новичок в 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 pickupDate startTime endTime gameDuration victoryTeam recordLocatorID pickupID

1546329808471 01/01/2019 08:03я 8:53 утра 50 минуту 2 f47ac0fc775cb5793-0a8a0-ad4789d4 216

pickup_results

1011 * ID checkSumID playerID команда gameResult pickOrder pickupRecordLocatorID

1 1535074728532 425336395712954388 1 потери 0 be3532dbb7fee8bde-2213c-5c5ce710

Ответы [ 2 ]

0 голосов
/ 22 января 2019

Сначала вы должны попытаться написать запрос 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();
0 голосов
/ 22 января 2019

По сути, я бы сократил запрос до его варианта SQL, чтобы получить непосредственно его ядро.Суть запроса:

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

Это может быть интерпретировано в Eloquent как:

$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
//)

Из полученного запроса может быть лучше выполнить рефакторинг объединения как отношения между Eloquentмодель для pickup_games и pickup_results.Это поможет еще больше упростить $playerIds.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...