Back to Course |
Laravel GroupBy: Practical Examples

Example 3. Grouping Orders by Week - Without Database

Another common way to use grouping is done by collections. This way, you don't have to do any database queries and just group already-fetched data. For example:

Our database currently looks like this:

And we get our data by a simple query:

$orders = Order::query()
->with(['products,' 'user'])
->get();

Now, we can display the orders table as usual, but we have a requirement to group orders by week. So, we will do it like this:

Controller

$orders = Order::query()
->with(['products', 'user'])
->get();
 
$orders = $orders
->groupBy(function (Order $order) {
// We are using Carbon to parse the date and get the start of the week for our group
return Carbon::parse($order->order_time)->startOfWeek()->format('Y-m-d');
})
// As a last step, we will sort the keys in descending order
->sortKeysDesc();
 
return view('orders.by-week', [
'orders' => $orders,
]);

Using our grouped entries in a view is very simple - just two foreach loops:

View

@foreach($orders as $week => $ordersList)
<h2 class="text-2xl font-bold mb-2">{{ $week }}</h2>
 
<table class="table-auto w-full mt-4 mb-4">
<thead>
<tr>
<th class="px-4 py-2">#</th>
<th class="px-4 py-2">User</th>
<th class="px-4 py-2">Order time</th>
<th class="px-4 py-2">Delivery time</th>
<th class="px-4 py-2">Total</th>
</tr>
</thead>
<tbody>
@foreach($ordersList as $order)
<tr>
<td class="border px-4 py-2">{{ $order->id }}</td>
<td class="border px-4 py-2">{{ $order->user->name }}</td>
<td class="border px-4 py-2">{{ $order->order_time }}</td>
<td class="border px-4 py-2">{{ $order->delivery_time }}</td>
<td class="border px-4 py-2">${{ number_format($order->total, 2) }}</td>
</tr>
@endforeach
</tbody>
</table>
@endforeach

This runs a straightforward query on the database:

select * from `orders`

And the result is:

Warning: Doing such transformations on the collection level can be slow and even crash your application if you have a lot of data. So, be careful when doing this, and always test it with a lot of data.