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

Tangaye's avatar

How to format or rearrange inner join query results in laravel view or controller

I have five table students, grades, subjects, terms, and scores. I'm performing an inner join on thes table to return results. This how my schema looks:

Students table:

students
--------
id *
name
class_id (fk)

Subjects table:

subjects
--------
id *
name

Class table:

classes
--------
id *
name

Term table:

terms
--------
id *
name

Scores Table:

scores
---------------
id *
student_id (fk)
subject_id (fk)
class_id (fk)
term_id (fk)
score

My laravel query:

$scores = \DB::table('scores')
        ->join('students', 'students.id', '=', 'scores.student_id')
        ->join('subjects', 'subjects.id', '=', 'scores.subject_id')
        ->join('grades', 'grades.id', '=', 'scores.grade_id')
        ->join('terms', 'terms.id', '=', 'scores.term_id')
        ->select('students.first_name', 'students.surname', 'subjects.name as subject', 'grades.name as grade', 'terms.name as term', 'score')
        ->where('students.id', 1)
        ->whereBetween('scores.term_id', [1, 3])
        ->get();

result return by the query when I die and dump it:

enter image description here

Without doubt the query is returning the right result, but the problem is I want the result to appear in my html table like this:

enter image description here

This is how it is displaying based on the code I now have in my controller and view.

controller:

public function index()
{
    //
    $scores = \DB::table('scores')
        ->join('students', 'students.id', '=', 'scores.student_id')
        ->join('subjects', 'subjects.id', '=', 'scores.subject_id')
        ->join('grades', 'grades.id', '=', 'scores.grade_id')
        ->join('terms', 'terms.id', '=', 'scores.term_id')
        ->select('students.first_name', 'students.surname', 'subjects.name as subject', 'grades.name as grade', 'terms.name as term', 'score')
        ->where('students.id', 1)
        ->whereBetween('scores.term_id', [1, 3])
        ->get();


    // finding details of the student based on id pased
    $student = Student::findOrFail(1);

    // getting the name of the student
    $name = $student->first_name.' '.$student->surname;

    // getting the class or grade of the student (grade 12 or grade 11)
    $grade = $student->grade->name;

    // getting the current date
    $date = Score::date();

    return view('scores.home', compact('scores', 'name', 'date', 'grade'));

view:

<table class="table table-bordered table-condensed table-striped">
    <thead>
        <tr>
            <th scope="row">Name</th>
            <td colspan="4">{{$name}}</td>
        </tr>
        <tr>
            <th scope="row">Class</th>
            <td colspan="2">{{$grade}}</td>

            <th scope="row">Date</th>
            <td>{{$date->toFormattedDateString()}}</td>
        </tr>
        <tr>
            <th class="text-center">Subject</th>
            @foreach($scores as $score)
                <th class="text-center">{{$score->term}}</th>
            @endforeach
        </tr>
    </thead>
    <tbody>
        @foreach($scores as $score)
            <tr>
                <td>{{$score->subject}}</td>
                <td>{{$score->score}}</td>
            </tr>
        @endforeach
    </tbody>
</table>

result:

enter image description here

As seen in the result above the term name 1st Period is being repeated, how do I avoid that? How do I refactor my query or code in view or controller to get the desire results that I want?

0 likes
2 replies
hondnl's avatar

You could take a look at Laravel's Collection function GroupBy

https://laravel.com/docs/5.4/collections#method-groupby

Just a question.. Do you need the periods to be dynamic ?

.. and another thing. Since you are fetching the student anyway, you don't need to join him in .

If looking at what you want.

The array/collection to match your table should contain

[Unique First Subject] [first_period] ['score'] [second_period] ['score'] ....

[Unqiue Second Subject] [first_period] ['score'] [second_period] ['score'] ...

Tangaye's avatar

@hondl I need the a student(siafa) score for subject(math) for first period(90) second period(99) and third period(88). What do you mean by asking if I need the periods to be dynamic? Please note that I'm actually working on a School Management System for secondary schools in my country. Now, normally there are eight terms six of them are periods and two of them are exams time. Since I'm planning on this being a saas application I can't specify the amount of terms a school may have. For more information on the design please take a look at this thread: https://stackoverflow.com/questions/45170192/how-to-rearrange-results-returned-by-inner-join-query

Please or to participate in this conversation.