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

PavanKataria's avatar

GROUP BY on eager loaded table.

GENDER | total_students
0   |    9
1   |    14

p.s. This is a table which shows a total students of 23. That gives 9 male students, and 14 female students.

To simplify the question, I'm trying to produce the above result set with as much eloquent as possible. Here's what the required SQL query looks like to produce the above result:

SELECT persons.gender, COUNT(*) as 'total_students' FROM student_enrolments as se

LEFT JOIN students on se.student_id = students.id
LEFT JOIN persons on students.person_id= persons.id

GROUP BY persons.gender

Here’s what I’ve tried so far to recreate this in eloquent:

StudentEnrolment::with([
        'student.person' => function($q){
            $q->groupBy('gender');
        }
    ])
        ->selectRaw('count(*) as total_students')
        ->get()
        ->toArray()

Notice the inner Group by to reach the gender attribute on the person table that belongs to the student model. But that produces the following incorrect query:

string 'select count(*) as total_students from `student_enrolments`' (length=59)

And when var dumping the toArray result… I get the following:

array (size=2)
      'total_students' => int 23 //<-notice how GROUP BY had no affect in splitting the result
      ...

And instead, I expected the result:

array (size=2)
  0 => 
    array (size=2)
      'total_students' => int 9
..
  1 => 
    array (size=2)
      'total_students' => int 14
..

I also tried doing a group by as a chain but by trying to reference the column with dot syntax like so: StudentEnrolment::with('student.person')->groupBy(‘student.person.gender’)t that didn't work too.

What can I do to get this working?

0 likes
0 replies

Please or to participate in this conversation.