Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

DogRocker's avatar

How to select last row for each group?

Hello, I try to select last row for each group with many to many table.

This is my schema.

table vehicles
id
1
2
table regis_history
vehicle_id     regis_id     created_at
1                      1                   yesterday
1                      2                  today
table regis
id
1
2

Now I use this query to select all vehicle with have regis or not have regis. And if it have regis I try to select the last row of regis that group by vehicle_id.

$vehicle = Vehicle::leftJoin('registration_history AS rh', 'vehicles.id', '=', 'rh.vehicle_id')
            ->leftJoin('registrations AS r', 'rh.registration_id', '=', 'r.id')
            ->select(*)
            ->groupBy('rh.vehicle_id')
            ->orderBy('rh.created_at', 'desc')
            ->get();

But It alway select the yesterday row.

How to get the today row ?

Thank you for help.

0 likes
5 replies
jakeryansmith's avatar

If you want just the last row then you want to order the results so the last row actually comes first then instead of using "get" which will retrieve all rows use first:

$vehicle = Vehicle::leftJoin('registration_history AS rh', 'vehicles.id', '=', 'rh.vehicle_id')
            ->leftJoin('registrations AS r', 'rh.registration_id', '=', 'r.id')
            ->select(*)
            ->groupBy('rh.vehicle_id')
            ->orderBy('rh.created_at', 'desc')
            ->first();
DogRocker's avatar

Thanks, @jakeryansmith. But I want all vehicles. The last row I want from registration_history that group by vehicle_id.

Here Is example

table regis_history
vehicle_id     regis_id     created_at
1                      1                   yesterday
1                      2                  today
2                     1                   yesterday

Result I want are.

vehicle_id     regis_id       created_at
1                        2                  today
2                        1                   yesterday
ZetecVan's avatar

You could try using MAX. That will return the record with the largest value for each group.

$vehicle = Vehicle::leftJoin('registration_history AS rh', 'vehicles.id', '=', 'rh.vehicle_id')
            ->leftJoin('registrations AS r', 'rh.registration_id', '=', 'r.id')
            ->select(*)
            ->groupBy('rh.vehicle_id')
            ->max('rh.created_at')
            ->get();
pmall's avatar

Add a boolean field in the registration_history to store whether it is the last registration or not. Update it when you add a registration.

Please or to participate in this conversation.