php - Laravel - code optimization for selecting column differences within 7 days
one text
I have this code. Finally, the player is returned with the levelDifference attribute for every day 7 days back. Could this be optimized to one sql query instead of looping and doing 7 queries?
Also, I would like to know if you can omit withMin and withMax and just get the difference between the smallest and the largest lvl on a given day?
$days = collect();
foreach (range(1, 7) as $dayNumber) {
$data = $game->players()
->withMin(
['statistics' => fn ($query) => $query->whereDate('created_at', '=', now()->subDays($dayNumber))],
'level'
)
->withMax(
['statistics' => fn ($query) => $query->whereDate('created_at', '=', now()->subDays($dayNumber))],
'level'
)
->get();
$filtered = $data->filter(function ($item) {
return $item->statistics_min_level && $item->statistics_max_level;
});
$dayStats= $filtered->values()->map(function ($item) {
$item->levelDifference = $item->statistics_max_level - $item->statistics_min_level;
return $item;
});
$days->put(
$dayNumber,
$dayStats
);
}
return $days;
Table schema
Schema::create('player_statistics', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('player_id');
$table->unsignedInteger('level');
$table->timestamps();
$table->foreign('player_id')->references('id')->on('players')->onUpdate('cascade')->onDelete('cascade');
$table->index(['player_id', 'created_at']);
});
Sample expected response
[
{
...user1,
statistics: [
1: { // 1 a day back
"minLevel": 5,
"maxLevel": 10
"levelDifference": 5,
},
2: { // 2 is 2 days back
"minLevel": 10,
"maxLevel": 20
"levelDifference": 10,
}
]
},
{
...user2,
statistics: [
1: {
"minLevel": 5,
"maxLevel": 10
"levelDifference": 5,
},
2: {
"minLevel": 10,
"maxLevel": 20
"levelDifference": 10,
}
]
}
]
Source