web-dev-qa-db-ja.com

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)を犯したように感じます。

関連するハッカソン参加者の最大数に基づいた最も人気のあるハッカソンを取得しようとするにはどうすればよいですか?

39
Joe Torraca

CollectionsortBy()およびcount()メソッドを使用して、これをかなり簡単に行うことができるはずです。

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

これはLaravel 5.3であなたの例を使って動作します:

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

このように、クエリで順序付けされ、ページネーションがうまく機能します。

109
kJamesy

別のアプローチは、withCount()メソッドを使用することです。

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

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

16
tisuchi

Sabrina Gelbartが以前のソリューションでコメントしたとおり、ページネーションが原因でsortBy()を使用するのは適切ではありません。そこで、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);   
13
Johnyz

結合演算子を使用することもできます。 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