【问题标题】:How to get count and avg of results in Laravel 5.8如何在 Laravel 5.8 中获取结果的计数和平均值
【发布时间】:2019-09-17 14:27:18
【问题描述】:

我有以下查询返回所有图书馆中所有可用的小说书籍:

$results = Library::with('category.books')
    ->whereHas('category.books', function($query) {
        $query->where('available', 1);
    })
    ->whereHas('category', function($query) {
        $query->where('name', 'fiction');
    })
    ->get();

现在,获取每个图书馆的图书总数和每本书的平均评分(图书有字段rating)的最佳方法是什么?

我假设我必须以某种方式创建这些结果的集合,应用自定义函数。

【问题讨论】:

    标签: laravel laravel-5


    【解决方案1】:

    您可以在使用map() 函数对其进行更改的同时获取所有库。

    您可以使用count() 函数计算集合中的项目数。

    您可以使用average() 函数通过集合中项目的属性获取平均值。

    $libraries = $results->map(function($library) {
    
        // All the books of the library
        $books = $library->category->flatMap->books;
    
        // set book count and average rating to the library object
        $library->book_count = $books->count();
        $library->average_rating = $books->average('rating');
    
        return $library;
    });
    

    现在$libraries 集合中的每个库对象都有这两个新属性,称为book_countaverage_rating

    【讨论】:

    • 删除了我的答案。这太干净了,你用flatMap教了我一些东西。不错。
    • 在上面的代码中,我假设$result-> 需要是$library->?
    • 不。它是您已经获取的结果。您在问题中发布的确切代码。
    • @TharakaDilshan 知道了,但需要是复数 $results-> 而不是 $result->
    【解决方案2】:

    这可以通过多种方式实现。根据您的结果:

    $libraries = Library::with('category.books')
        ->whereHas('category.books', function($query) {
            $query->where('available', 1);
        })
        ->whereHas('category', function($query) {
            $query->where('name', 'fiction');
        })
        ->get();
    
    $books = $libraries->map(function ($library) {
        return $library->category->books;
    })
    ->collapse()
    ->filter(); // This is an optional step to remove NULL books, if there are any.
    
    $count = $books->count();
    
    $avg = $books->avg('rating'); // Or $books->average('rating');
    

    但我认为更好的方法可能是从 Book 开始的查询中计算计数和平均值,如果您还没有,让我们在模型类中定义一个名为 category 的关系:

    class Book
    {
        // This could be a different type of relationships.
        public function category()
        {
            return $this->belongsTo('category');
        }
    }
    

    然后写一个查询。

    $query = Book::where('available', 1) 
        ->whereHas('category', function($query) {
            $query->where('name', 'fiction');
        });
    
    $count = $query->count();
    $avg = $query->avg(); // Or $query->average();
    

    【讨论】:

    • 错误答案。他需要(计数和平均)每个图书馆,而不是所有的书。
    【解决方案3】:

    您只需要在图书馆模型中定义图书平均数和评分的关系,如下所示。我希望您在 books 表中有一个 library_id 列。

    In your library model. 
    
    public function TotalBooks()
    {  
        return $this->hasMany('App\Books', 'library_id')
            ->selectRaw('SUM(id) as total_book'); 
    }
    
    public function AvgRating()
        {  
            return $this->hasMany('App\Books', 'library_id')
                ->selectRaw('AVG(rating) as avg_arting');
        }
    
    $data = Library::with('TotalBooks')->with('AvgRating');   // Get record 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-05
      • 1970-01-01
      • 2018-06-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多