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

sheldonscott's avatar

Using Laravel to average values, group by a category and a date range, and show the output on a single page

I have a table that looks something like this:

https://i.stack.imgur.com/4XhZu.png

I want to be able to query this table and display results based on grouping by subject and by date. The dates would satisfy a range (between x and y).

I am looking to output something like this:

Term 1 - Art - (average of all asssessed_level for x range)

Term 2 - Art - (average of all asssessed_level for y range)

Term 3 - Art - (average of all asssessed_level for z range) And this:

Term 1 - Math - (average of all asssessed_level for x range)

Term 2 - Math - (average of all asssessed_level for y range)

Term 3 - Math - (average of all asssessed_level for z range) (etc.)

If there is no assessed_level for a date range, then I still need it to return a subject with perhaps an 'N/A' for that spot.

Ultimately, I want a table of data that will look something like this:

https://i.stack.imgur.com/YWscV.png

('E' would be where the average assessed_level goes and the YEAR column would be a result that is averaged and ignores the date range)

This is the code that I have written, but it doesn't provide the results that I need:

for($b=0; $b < $assessed_subjects->count(); $b++) {
    $assessment_strengths[] = DB::table('assessment_data')
        ->join('subjects', 'assessment_data.subject_id', '=', 'subjects.id')
        ->join('units', 'assessment_data.unit_id', '=', 'units.id')
        ->join('outcomes', 'assessment_data.outcome_id', '=', 'outcomes.id')
        ->join('assessments', 'assessment_data.assessment_id', '=', 'assessments.id')
        ->select('subjects.short_name as subject_name', 'units.name as unit_name', 'outcomes.name as outcome_name', 'assessments.assessment_name as assessment_name', 'assessment_data.*')
        ->where('assessment_data.user_id', 28)
        ->where('assessment_data.student_id', $student_id)
        ->where('assessment_data.subject_id', $assessed_subjects[$b]->id)
        ->whereBetween('assessment_data.created_at', [$current_term->term_start, $current_term->term_end])
        ->orderBy('assessment_data.assessed_level', 'desc')
        ->get();
}

This is the output that I get when I dd() the query:

array:8 [▼
  0 => Collection {#371 ▼
    #items: []
  }
  1 => Collection {#386 ▼
    #items: []
  }
  2 => Collection {#392 ▼
    #items: array:1 [▼
      0 => {#390 ▼
        +"subject_name": "Math"
        +"unit_name": "Rocks and Minerals"
        +"outcome_name": "Analyze how positive health habits can be supported by a variety of approaches to health practices and treatments"
        +"assessment_name": "The First Assessment"
        +"id": 36
        +"user_id": 28
        +"room_id": 1
        +"assessment_id": 1
        +"student_id": 6
        +"subject_id": 19
        +"unit_id": 188
        +"outcome_id": 476
        +"assessed_level": 4.0
        +"created_at": "2018-03-29 10:04:42"
        +"updated_at": "2018-03-29 10:04:42"
      }
    ]
  }
  3 => Collection {#399 ▼
    #items: array:1 [▼
      0 => {#397 ▼
        +"subject_name": "Social"
        +"unit_name": "Animals"
        +"outcome_name": "Demonstrate and explain the effect of adding zero to, or subtracting zero from, any number."
        +"assessment_name": "The First Assessment"
        +"id": 48
        +"user_id": 28
        +"room_id": 1
        +"assessment_id": 1
        +"student_id": 6
        +"subject_id": 25
        +"unit_id": 122
        +"outcome_id": 27
        +"assessed_level": 4.0
        +"created_at": "2018-01-01 10:04:42"
        +"updated_at": "2018-03-29 10:04:42"
      }
    ]
  }
  4 => Collection {#406 ▼
    #items: []
  }
  5 => Collection {#412 ▼
    #items: []
  }
  6 => Collection {#418 ▼
    #items: array:1 [▼
      0 => {#416 ▼
        +"subject_name": "ELA"
        +"unit_name": "Explore - Clarify and Extend"
        +"outcome_name": "State, orally in their own words, that in French the indefinite article is not used when identifying one’s profession (e.g., m. brown est dentiste.)"
        +"assessment_name": "The First Assessment"
        +"id": 18
        +"user_id": 28
        +"room_id": 1
        +"assessment_id": 1
        +"student_id": 6
        +"subject_id": 6
        +"unit_id": 25
        +"outcome_id": 3000
        +"assessed_level": 4.0
        +"created_at": "2018-03-29 10:04:42"
        +"updated_at": "2018-03-29 10:04:42"
      }
    ]
  }
  7 => Collection {#425 ▼
    #items: []
  }
]

As you can see, there are empty values (0, 1, 4, 5, 7) that I would like to push some data to. I took a look at IFNULL and COALESCE as a way of providing a fall-back, but that wasn't helpful in this case. Is there a way to append (or something like that) values into query results, even if they are otherwise empty?

My thought process is that if I can define each of the records that are being output as belonging to a specific term, I will be closer to having what I need.

0 likes
3 replies
jlrdw's avatar

For that sort of thing I would use normal PDO and sql via getPdo ().

sheldonscott's avatar

Always appreciate your replies, man. I’ll give that a go!

Please or to participate in this conversation.