Php laravel查询一个';它被称为pior

Php laravel查询一个';它被称为pior,php,laravel,laravel-5,Php,Laravel,Laravel 5,我有下面的代码来获取一个模型的所有评级信息,正如你所看到的,有很多查询正在进行,只是为了评级信息,这个函数可以做得更好,特别是对于查询负载,所以它不会在每次请求此信息时耗尽服务器 public function ratingInfo() { $totalCount = $this->ratings()->count(); $one_star = $this->ratings()->where('rating', '>', 0)->

我有下面的代码来获取一个模型的所有评级信息,正如你所看到的,有很多查询正在进行,只是为了评级信息,这个函数可以做得更好,特别是对于查询负载,所以它不会在每次请求此信息时耗尽服务器

public function ratingInfo() {

    $totalCount  = $this->ratings()->count();  
    $one_star    = $this->ratings()->where('rating', '>', 0)->where('ratings', '<=', 1);
    $two_star    = $this->ratings()->where('rating', '>', 1)->where('ratings', '<=', 2);
    $three_star  = $this->ratings()->where('rating', '>', 2)->where('ratings', '<=', 3);
    $four_star   = $this->ratings()->where('rating', '>', 3)->where('ratings', '<=', 4);
    $three_star  = $this->ratings()->where('rating', '>', 4)->where('ratings', '<=', 5);

    return [
        'avgRating'   => $this->avgRating(),
        'ratingCount' => $this->ratingCount(),
        'one_star'    => ['count' => $one_star->count(),  'percent' => round(($one_star->count()   * $totalCount) / 100, 2)],
        'two_star'    => ['count' => $two_star->count(),  'percent' => round(($two_star->count()   * $totalCount) / 100, 2)],
        'three_star'  => ['count' => $two_star->count(),  'percent' => round(($three_star->count() * $totalCount) / 100, 2)], 
        'four_star'   => ['count' => $four_star->count(), 'percent' => round(($four_star->count()  * $totalCount) / 100, 2)], 
        'five_star'    => ['count' => $five_star->count(), 'percent' => round(($five_star->count()  * $totalCount) / 100, 2)], 
    ];
}
评级模式:

class Rating extends Model
{
    protected $table = 'ratings';

    protected $fillable = ['rating', 'comment', 'user_id', 'rateable_id', 'rateable_type'];   

    public function rating()
    {
        return $this->morphTo();
    } 
}
答案是:

public function ratingInfo() {

    $result = [];

    $one_star = $this->ratings->filter(function ($item, $key) { 
        return $item->rating > 0 && $item->rating <= 1;
    });

    $two_star = $this->ratings->filter(function ($item, $key) { 
        return $item->rating > 1 && $item->rating <= 2;
    });

    $three_star = $this->ratings->filter(function ($item, $key) { 
        return $item->rating > 2 && $item->rating <= 3;
    });

    $four_star = $this->ratings->filter(function ($item, $key) { 
        return $item->rating > 3 && $item->rating <= 4;
    });

    $five_star = $this->ratings->filter(function ($item, $key) { 
        return $item->rating > 4 && $item->rating <= 5;
    });

    $totalCount = $this->ratings->count();  
    $avgRating = $this->avgRating(2);  
    $totalRatings = $this->ratings->sum('rating');
    //dd('sum: ' . $one_star->sum('rating') . ' count: ' . $one_star->count() . ' percent: ' . round(($one_star->sum('rating') / $this->ratings->sum('rating')) * 100, 2));

    return [
    'total_count' => $totalCount,
    'average_rating' => $avgRating,
    'total_ratings' => $totalRatings,
        'one_star' => [
            'sum' => $one_star->sum('rating'),
            'count' => $one_star->count(),
            'percent' =>  round(($one_star->sum('rating') / $totalRatings) * 100, 2)
        ],
        'two_star' => [
            'sum' => $two_star->sum('rating'),
            'count' => $two_star->count(),
            'percent' =>  round(($two_star->sum('rating') / $totalRatings) * 100, 2)
        ],
        'three_star' => [
            'sum' => $three_star->sum('rating'),
            'count' => $three_star->count(),
            'percent' =>  round(($three_star->sum('rating') / $totalRatings) * 100, 2)
        ],
        'four_star' => [
            'sum' => $four_star->sum('rating'),
            'count' => $four_star->count(),
            'percent' =>  round(($four_star->sum('rating') / $totalRatings) * 100, 2)
        ],
        'five_star' => [
            'sum' => $five_star->sum('rating'),
            'count' => $five_star->count(),
            'percent' =>  round(($five_star->sum('rating') / $totalRatings) * 100, 2)
        ]
    ];
}
public function ratingInfo(){
$result=[];
$one_star=$this->ratings->filter(函数($item,$key){
返回$item->rating>0&&$item->rating ratings->filter(函数($item,$key){
返回$item->rating>1&&$item->rating ratings->filter(函数($item,$key){
返回$item->rating>2&&$item->rating ratings->filter(函数($item,$key){
返回$item->rating>3&&$item->rating ratings->filter(函数($item,$key){
返回$item->rating>4&&$item->rating ratings->count();
$avgRating=$this->avgRating(2);
$totalRatings=$this->ratings->sum('rating');
//dd($one'u star->sum('rating')。'count:'。$one'u star->count()。'percent:'。四舍五入($one'u star->sum('rating')/$this->ratings->sum('rating'))*100,2);
返回[
“总计数”=>$totalCount,
“平均评级”=>$avg,
“总评分”=>$totalRatings,
“一颗星”=>[
“总和”=>一颗星->总和(“评级”),
“count”=>$one_star->count(),
“百分比”=>round($one_star->sum('rating')/$totalRatings)*100,2)
],
“双星”=>[
“总和”=>$2星->总和(“评级”),
“count”=>$two_star->count(),
“百分比”=>round($two_star->sum('rating')/$totalRatings)*100,2)
],
“三星”=>[
“总和”=>三星->总和(“评级”),
“计数”=>$三星->计数(),
“百分比”=>四舍五入($三星->总和(“评级”)/$totalRatings)*100,2)
],
“四星”=>[
“总和”=>四颗星->总和(“评级”),
“计数”=>$4星->计数(),
“百分比”=>四舍五入($4星->总和('rating')/$totalRatings)*100,2)
],
“五星”=>[
“总和”=>五星->总和(“评级”),
“计数”=>$five_star->count(),
“百分比”=>四舍五入($five_star->sum('rating')/$totalRatings)*100,2)
]
];
}

我会尝试以下方法:

$this->ratings()->selectRaw('rating, count(*) as C')
     ->groupBy('rating')
     ->orderBy('rating', 'DESC');
public function ratingInfo() {

    $all = $this->ratings()->get();
    $count = $all->count();
    $one_star = $all->filter(function ($item, $key) {
        return $item->rating === 1;
    });
    $two_star = $all->filter(function ($item, $key) {
        return $item->rating === 2;
    });
    $three_star = $all->filter(function ($item, $key) {
        return $item->rating === 3;
    });
    $four_star = $all->filter(function ($item, $key) {
        return $item->rating === 4;
    });
    $five_star = $all->filter(function ($item, $key) {
        return $item->rating === 5;
    });

    return [
        'avgRating'   => $this->avgRating(),
        'ratingCount' => $this->ratingCount(),
        'one_star'    => ['count' => $one_star->count(),  'percent' => round(($one_star->count()   * $totalCount) / 100, 2)],
        'two_star'    => ['count' => $two_star->count(),  'percent' => round(($two_star->count()   * $totalCount) / 100, 2)],
        'three_star'  => ['count' => $two_star->count(),  'percent' => round(($three_star->count() * $totalCount) / 100, 2)], 
        'four_star'   => ['count' => $four_star->count(), 'percent' => round(($four_star->count()  * $totalCount) / 100, 2)], 
        'five_star'    => ['count' => $five_star->count(), 'percent' => round(($five_star->count()  * $totalCount) / 100, 2)], 
    ];
}
这样做的目的是获得一行中每个等级的计数1-5,每个等级都有各自的计数

$this->whereHas('ratings', function($query) {
      $query->selectRaw('rating, count(*) as C')
            ->groupBy('rating')
            ->orderBy('rating', 'DESC')
})->get();
执行此操作时出错:

$all = $this->ratings()->get();

return $all;
您可以通过这样做进一步简化

$this->ratings->groupBy('rating')->each(function ($group) {
     return count($group);
});

您可以使用php执行一次查询并过滤结果,如下所示:

$this->ratings()->selectRaw('rating, count(*) as C')
     ->groupBy('rating')
     ->orderBy('rating', 'DESC');
public function ratingInfo() {

    $all = $this->ratings()->get();
    $count = $all->count();
    $one_star = $all->filter(function ($item, $key) {
        return $item->rating === 1;
    });
    $two_star = $all->filter(function ($item, $key) {
        return $item->rating === 2;
    });
    $three_star = $all->filter(function ($item, $key) {
        return $item->rating === 3;
    });
    $four_star = $all->filter(function ($item, $key) {
        return $item->rating === 4;
    });
    $five_star = $all->filter(function ($item, $key) {
        return $item->rating === 5;
    });

    return [
        'avgRating'   => $this->avgRating(),
        'ratingCount' => $this->ratingCount(),
        'one_star'    => ['count' => $one_star->count(),  'percent' => round(($one_star->count()   * $totalCount) / 100, 2)],
        'two_star'    => ['count' => $two_star->count(),  'percent' => round(($two_star->count()   * $totalCount) / 100, 2)],
        'three_star'  => ['count' => $two_star->count(),  'percent' => round(($three_star->count() * $totalCount) / 100, 2)], 
        'four_star'   => ['count' => $four_star->count(), 'percent' => round(($four_star->count()  * $totalCount) / 100, 2)], 
        'five_star'    => ['count' => $five_star->count(), 'percent' => round(($five_star->count()  * $totalCount) / 100, 2)], 
    ];
}

尝试使用case表达式构建一个数据透视函数,将结果作为一个查询执行的一部分,这将大大优化服务器负载,请注意mysql没有本机数据透视函数,这就是为什么我建议您使用case表达式, 然后,您必须使用laravel查询生成器方法将查询作为原始查询执行。。 以下仅为示例,请尝试相应地重写并运行它

select id,
sum(case when value = 1 then 1 else 0 end) ANSWER1_COUNT,
sum(case when value = 2 then 1 else 0 end) ANSWER2_COUNT
from survey
group by answer

我试着做你的例子,但我没有提到ratings()是一个多变量关系。我在你的代码中得到了以下错误-调用undefined方法illumb\Database\Query\Builder::ratings(),试试看,多态关系现在应该解决了。如果不这样做,就试试$this->ratings->…不带()几乎在那里,但我现在发现了此错误列未找到:'order子句'中的1054未知列'DESC'忘记了order by子句中的列…doh!我得到了一个空数组,但有数据我使用对成员函数AddagerConstraints()的示例调用得到此错误在arrayI上又增加了一个可能性,这次只对评级进行了收集操作