How to get average with orderBy Desc in Laravel 5

后端 未结 3 1134
长情又很酷
长情又很酷 2021-01-20 21:07

I have 2 tables in my database.

books and ratings

in books id, name

in ratings

相关标签:
3条回答
  • 2021-01-20 21:31

    That query would look something like this:

    SELECT book.id, AVG(ratings.rating) AS avg_rating 
    FROM ratings
    JOIN book ON book.id = ratings.book_id
    /* WHERE AVG(ratings.rating) > 4 You could say only return results where rating > 4 */
    GROUP BY book.id
    ORDER BY AVG(ratings.rating) DESC LIMIT 5;
    

    You need to join the two tables, use an aggregate function with a group by on the book. Then just sort and limit the results.

    UPDATE:

    In response to your question:

    SELECT book.id, COALESCE(AVG(ratings.rating), 0) AS avg_rating 
    FROM book
    *LEFT* JOIN ratings ON book.id = ratings.book_id    
    GROUP BY book.id
    ORDER BY AVG(ratings.rating);
    

    Use of a view might be something of a compromise between ease of the ORM and sanity in your querying.

    0 讨论(0)
  • 2021-01-20 21:39

    Via Collections*

        $books = Book::with('ratings')
            ->get()
            ->sortBy(function($bk, $key) {
                if($bk->rating) {
                    return $bk->rating->rating;
                }
                return null;
            });
    

    Via Joins

      $books = Book::join('rating', 'rating.book_id', '=', 'book.id')
                     ->orderBy('ratings.rating', 'desc')
                     ->select('books.*')
                     ->get();
    
    0 讨论(0)
  • 2021-01-20 21:50

    You can use a modified withCount():

    $books = Book::withCount(['ratings as average_rating' => function($query) {
        $query->select(DB::raw('coalesce(avg(rating),0)'));
    }])->orderByDesc('average_rating')->get();
    
    0 讨论(0)
提交回复
热议问题