如何补全数据库中当前周7条最新记录的缺失日期?
Fix: Fill Missing Weekly Dates with Null for UserStrike Records
Here's how to get an array of 7 entries (one per day from Sunday to Saturday) where missing dates are replaced with null:
Step-by-Step Solution
- Generate all days in the current week: Create a fixed list of every date in the week to establish the structure we need to fill.
- Fetch and group existing strikes: Pull the user's records for the week and group them by their creation date for quick lookup.
- Map days to records: Loop through each day in the week, adding the corresponding strike (or
null) to the final array.
Working Code
// Set week boundaries to Sunday-Saturday Carbon::setWeekStartsAt(Carbon::SUNDAY); Carbon::setWeekEndsAt(Carbon::SATURDAY); $startOfWeek = Carbon::now()->startOfWeek(); $endOfWeek = Carbon::now()->endOfWeek(); // 1. Create array of all 7 days in the week $weekDays = []; for ($i = 0; $i < 7; $i++) { $day = $startOfWeek->copy()->addDays($i); $weekDays[] = [ 'date' => $day->format('Y-m-d'), 'short_name' => $day->format('D') // e.g., Sun, Mon ]; } // 2. Get user's strikes grouped by date $strikesByDate = UserStrike::where('user_id', $user) ->whereBetween('created_at', [$startOfWeek, $endOfWeek]) ->get() ->groupBy(fn($strike) => $strike->created_at->format('Y-m-d')); // 3. Build the final array with nulls for missing days $weeklyStrikes = []; foreach ($weekDays as $day) { // Use the latest strike for the day if multiple exist $strike = $strikesByDate->get($day['date']); $weeklyStrikes[] = $strike ? $strike->last() : null; } // If you just want day names + null (matching your example): // $weeklyDays = array_map(function($day) use ($strikesByDate) { // return $strikesByDate->has($day['date']) ? $day['short_name'] : null; // }, $weekDays);
Breakdown
- Generating Week Days: We loop from Sunday to Saturday, storing each date's string format and short name. This gives us a guaranteed 7-item structure to work with.
- Grouping Strikes: Grouping by date lets us quickly check if there's a record for any given day without redundant loops through all records.
- Filling Nulls: For each day in our week list, we check if there's a matching group of strikes. If yes, we take the latest one (since
groupBypreserves the query's order). If not, we addnull.
This ensures your final array always has 7 elements, ordered from Sunday to Saturday, with gaps filled in as null.
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

