php-Laravel OrderBy关系计数

我正在尝试获得最受欢迎的黑客马拉松,这需要通过相应的黑客马拉松的Hackathon::orderBy(HackathonParticipant::find($this->id)->count(), 'DESC')->take(5)->get());216进行订购。很抱歉,这有点难以理解。

我有以下格式的数据库:

hackathons
    id
    name
    ...

hackathon_user
    hackathon_id
    user_id

users
    id
    name

Hackathon::orderBy(HackathonParticipant::find($this->id)->count(), 'DESC')->take(5)->get());型号为:

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');
    }
}

Hackathon::orderBy(HackathonParticipant::find($this->id)->count(), 'DESC')->take(5)->get());定义为:

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),因为它根本无法工作。

我将如何尝试获得基于最多的相关hackathon参与者的最受欢迎的hackathon?

Joe Torraca asked 2020-08-01T09:13:13Z
5个解决方案
116 votes

使用您的示例,这在Laravel 5.3中对我有效:

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

这样,它就可以在查询中排序,并且分页效果很好。

kJamesy answered 2020-08-01T09:14:02Z
35 votes

编辑:如果使用Laravel 5.2或更高版本,请使用kJamesy的答案。 它的性能可能会更好一些,因为它不需要将所有参与者和hackathon加载到内存中,仅需要分页的hackathon和这些hackathon的参与者数。

您应该能够使用CollectionsortBy()count()方法来轻松地做到这一点。

$hackathons = Hackathon::with('participants')->get()->sortBy(function($hackathon)
{
    return $hackathon->participants->count();
});
user1669496 answered 2020-08-01T09:13:38Z
18 votes

另一种方法可以通过使用withCount()方法。

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

参考:[https://laravel.com/docs/5.5/eloquent-relationships#querying-relations]

tisuchi answered 2020-08-01T09:14:26Z
13 votes

我有类似的问题,由于分页,因此不适合使用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);   
Johnyz answered 2020-08-01T09:14:48Z
0 votes

您也可以使用联接运算符。 正如Sabrina所说,您不能在数据库级别使用sortby。

$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]

Muhammed Tanrıverdi answered 2020-08-01T09:15:16Z
translate from https://stackoverflow.com:/questions/24208502/laravel-orderby-relationship-count