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

abnersouza's avatar

Query using max and group

Guys,

I have the following scenario:

  1. I need to filter the latest version for each type.

My Collection is called Template, for the template I have the following columns in the DB:

variant (int) version (int) id_type(int)

For the given table data:

Row........: 1-----2-----3-----4-----5-----6

id_Type...: 1-----1-----1-----2-----2-----2

Variant....: 1-----1-----2-----1-----1-----1

Version...: 1-----2-----1-----1-----2-----3

So if i have the example above with 6 results i want the latest version of each variant and grouped by type (3 items in this case), my results would return only the following records:

Row........: 2-----3-----6

id_Type...: 1-----1-----2

Variant....: 1-----2-----1

Version...: 2-----1-----3

Wondering if anyone could help to create that query using the Eloquent/Query Builder

Today this is what i have, returns all the data the variants and versions.

$this->tableData = Template::leftJoin('qual_form_templates', 'template_templates.id', '=', 'qual_form_templates.template_id') ->with('type') ->select('template_templates.*', 'qual_form_templates.approved') ->get();

Thanks

0 likes
8 replies
tisuchi's avatar

Have you tried with the relationship? Here is the sample code of your idea.

In Template.php-


public function qualFormTemplate(){
    return $this->hasOne('App\QualFormTemplate');
}

In QualFormTemplate.php.

public function template(){
    return $this->hasOne('App\Template');
}

Now you can easily call data from the template model in your controller-

$templates = Template::with(['type', 'qualFormTemplate'])
    ->get();

Note: I haven't tested your code yet, hope it will work.

abnersouza's avatar

@tisuchi I already have relationship in place, the question here is how to query only the data that i need, from the example give, i need return filter 6 items and make them 3 items.

Having in my table the following rows: Row........: 1-----2-----3-----4-----5-----6

id_Type...: 1-----1-----1-----2-----2-----2

Variant....: 1-----1-----2-----1-----1-----1

Version...: 1-----2-----1-----1-----2-----3

I want to get back only 3 rows (colums here because i cannot use table in this texteditor)

Row........: 2-----3-----6

id_Type...: 1-----1-----2

Variant....: 1-----2-----1

Version...: 2-----1-----3

The latest variant and version of each type.

tisuchi's avatar

@ABNERSOUZA - Sorry. I am bit confused about your question.

You may use screenshot for better visualization.

jlrdw's avatar

A join and a group by example is something like

This is just an example:

$quy = Powner::query()->leftJoin('dc_pets', 'dc_powners.ownerid', '=', 'dc_pets.ownerid')
                ->select('dc_powners.ownerid', 'dc_powners.oname')
                ->selectRaw('count(dc_pets.petid) as countOfPets')
                ->groupby('dc_powners.ownerid')
                ->orderby('dc_powners.oname')
                ->get();

Results basically give:

ownerid, oname, countOfPets

Like:

5|Bob|3
4|Greg|9
2|Rob|1
// more

Example uses count just change to Max or whatever aggregate you need.

abnersouza's avatar

Hey @jlrdw this is the final query that i need to convert to use the builder:

SELECT T.*, QFT.approved FROM ( SELECT MAX(id) id, type_id, variant FROM template_templates GROUP BY type_id, variant) AS TT JOIN template_templates T ON TT.id = T.id LEFT JOIN qual_form_templates AS QFT ON TT.id = QFT.template_id;

jlrdw's avatar

It will be similar to my example and you have to remember these queries can take a little trial and error to work out just right.

Your aggregate will probably have to be a raw expression.

Just look in the docs under query Builder and Taylor has many examples.

Of course you can use DB facade also and just use your query as is if it works.

Please or to participate in this conversation.