Laravel OrderBy关系计数

时间:2014-06-13 15:04:57

标签: php mysql laravel eloquent

我正在尝试获得最受欢迎的黑客马拉松,这需要由相应的黑客马拉松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),因为它根本不起作用。

我将如何尝试获得最受欢迎的黑客马拉松,这些黑客马拉松是基于最多相关的黑客入侵者?

7 个答案:

答案 0 :(得分:98)

这在Laravel 5.3中对我有用,使用你的例子:

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

这种方式在查询中排序,分页效果很好。

答案 1 :(得分:32)

您应该可以使用Collection的{​​{1}}和sortBy()方法轻松完成此操作。

count()

答案 2 :(得分:17)

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

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

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

答案 3 :(得分:12)

我有类似的问题,使用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);   

答案 4 :(得分:0)

您还可以使用join运算符。正如Sabrina所说,你不能在db级别使用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

答案 5 :(得分:0)

您可以使用以下代码

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

或者,如果您甚至想要单一方法的 ASC/DESC

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

答案 6 :(得分:0)

我需要对多个计数求和,然后用它来设置顺序。以下查询在 Laravel 8 中对我有用。

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