Question

I have two tables: Workplans and Progress. Here is the Workplan table.

Workplan Table:

id

division_name

division_chief

Progress Table:

id

score

workplan_id foreign_key

Here workplan_id is foreign key of workplan table.

Now I want to get average from progress table grouping by the division_name. But I am really messed up with my query. What is I have done:

  $report = DB::table('workplans')
    ->join('progress','workplans.id','=','progress.workplan_id')
    ->avg('progress.score')
    ->groupBy('workplans.division_name')
    ->get();

  dd($report);
Was it helpful?

Solution

The SQL you want is something like this...

SELECT workplans.division_name, AVG(progress.score) as average_score
FROM `workplans` 
LEFT JOIN `progress` ON progress.workplan_id = workplans.id
GROUP BY workplans.id

With the laravel query builder...

$report = DB::table ('workplans')
  ->join ('progress', 'progress.workplan_id', '=', 'workplans.id')
  ->select ('workplans.division_name', DB::raw ('AVG(progress.score) as average_score'))
  ->groupBy ('workplans.id')
  ->get ();

So for division 1 with scores 5 and 15, division 2 with scores 15 and 25 this returns...

Array
(
    [0] => stdClass Object
        (
            [division_name] => Division 1
            [average_score] => 10
        )

    [1] => stdClass Object
        (
            [division_name] => Division 2
            [average_score] => 20
        )

)

The problem with your query is that the avg aggregate function returns the average value for all columns on the table, not a reference back to the query so that you can continue to chain additional functions. The solution to this is to manually specify the average using the MySQL AVG function using the DB::raw method.

OTHER TIPS

Try to do it via raw select:

$report = DB::table('workplans')
    ->join('progress','workplans.id','=','progress.activity_id')
    ->select(DB::raw('avg(progress.score) as avg_progress_score'))
    ->groupBy('workplans.division_name')
    ->get();

I'm not sure how to write it using Laravel's query builder, but a static MySQL query might be easier:

$report = DB::select("SELECT AVG(progress.score) AS 'avg' FROM workplans JOIN progress ON workplans.id=progress.activity_id GROUP BY workplans.division_name;");
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top