Laravel OrderBy 关系统计

我试图得到最流行的黑客马拉松,这需要订购各自的黑客马拉松的 partipants->count()。抱歉,如果这有点难以理解。

我有一个格式如下的数据库:

hackathons
id
name
...


hackathon_user
hackathon_id
user_id


users
id
name

Hackathon模式是:

class Hackathon extends \Eloquent {
protected $fillable = ['name', 'begins', 'ends', 'description'];


protected $table = 'hackathons';


public function owner()
{
return $this->belongsToMany('User', 'hackathon_owner');
}


public function participants()
{
return $this->belongsToMany('User');
}


public function type()
{
return $this->belongsToMany('Type');
}
}

HackathonParticipant的定义是:

class HackathonParticipant extends \Eloquent {


protected $fillable = ['hackathon_id', 'user_id'];


protected $table = 'hackathon_user';


public function user()
{
return $this->belongsTo('User', 'user_id');
}


public function hackathon()
{
return $this->belongsTo('Hackathon', 'hackathon_id');
}
}

我试过 Hackathon::orderBy(HackathonParticipant::find($this->id)->count(), 'DESC')->take(5)->get());,但我觉得我犯了一个大错误(可能是 $this-> id) ,因为它根本不起作用。

我如何去尝试获得最受欢迎的编程马拉松是基于最高数量的相关参与者的编程马拉松?

66795 次浏览

编辑: 如果使用 Laravel 5.2或更高版本,请使用 kJamesy 的回答。它可能会表现得更好一些,因为它不需要将所有参与者和编程马拉松加载到内存中,只需要分页编程的编程马拉松和这些编程马拉松的参与者人数。

您应该能够使用 CollectionsortBy()count()方法相当容易地完成这项工作。

$hackathons = Hackathon::with('participants')->get()->sortBy(function($hackathon)
{
return $hackathon->participants->count();
});

我遇到过类似的问题,使用 sortBy ()由于分页而不适合,正如 Sabrina Gelbart 在以前的解决方案中所说的那样。 所以我使用了 db raw,这里有一个简化的查询:

Tag::select(
array(
'*',
DB::raw('(SELECT count(*) FROM link_tag WHERE tag_id = id) as count_links'))
)->with('links')->orderBy('count_links','desc')->paginate(5);

您还可以使用连接操作符。

$hackathons = Hackathon::leftJoin('hackathon_user','hackathon.id','=','hackathon_user.hackathon_id')
->selectRaw('hackathon.*, count(hackathon_user.hackathon_id) AS `count`')
->groupBy('hackathon.id')
->orderBy('count','DESC')
->paginate(5);

但是这段代码从数据库中获取所有记录,所以应该手动分页。

       $hackathons = Hackathon::leftJoin('hackathon_user','hackathon.id','=','hackathon_user.hackathon_id')
->selectRaw('hackathon.*, count(hackathon_user.hackathon_id) AS `count`')
->groupBy('hackathon.id')
->orderBy('count','DESC')
->skip(0)->take(5)->get();

转自: https://stackoverflow.com/a/26384024/2186887

我在 Laravel 5.3中使用了这个例子:

Hackathon::withCount('participants')->orderBy('participants_count', 'desc')->paginate(10);

这样就可以对查询进行排序,并且分页效果很好。

另一种方法是使用 withCount()方法。

Hackathon::withCount('participants')
->orderBy('participants_count', 'desc')
->paginate(50);

档号: https://laravel.com/docs/5.5/eloquent-relationships#querying-relations

您可以使用以下代码

Hackathon::withCount('participants')->orderByDesc("participants_count")->paginate(15)

或者,如果您甚至希望使用单个方法进行 ASC/DESC

Hackathon::withCount('participants')->orderBy("participants_count", 'asc')->paginate(15)

我需要对多个计数进行求和,然后用它来设置顺序。下面的问题在 Laravel 8中对我很有用。

$posts = Post::withCount('comments','likes')->orderBy(\DB::raw('comments_count + likes_count'),'DESC')->get();