2014-06-13 99 views
17

我想要獲得最受歡迎的黑客馬拉松,它需要按各自的黑客馬拉松的partipants->count()進行訂購。對不起,如果這有點難以理解。Laravel OrderBy關係計數

我有以下格式的數據庫:

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),因爲它根本不起作用。

我該如何去嘗試獲得最流行的黑客馬拉松,這是基於相關黑客馬拉松參與者的最高數量?

回答

21

您應該能夠使用CollectionsortBy()count()方法很容易地完成此操作。

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

如何改變asending/desecnding? – FooBar

+2

'sortBy(Closure $ callback,$ options = SORT_REGULAR,bool $ descending = false)'只需將第三個參數設置爲true即可。 – user3158900

+19

排序依據不會在數據庫級別執行該操作...因此,它無法在分頁時正常工作!儘管如此,當你返回一套完整的套餐時很有用。 –

12

我有類似的問題,並使用sortBy()是不合適的,因爲分頁的,正是因爲塞布麗娜吉爾巴特在以前的解決方案評論。 所以我用分貝原料,這裏的一個簡化查詢:

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); 
+1

我發現了Laravel的早期版本的最佳解決方案! (新的可以使用withCount)不知道它是什麼,但我已經做了:'tag_id = tag.id'而不是'tag_id = id' ...此外,你可以更簡化這個!而不是'select',你可以像count_links')DESC') - > paginate(5)'那樣做'orderByRaw('(SELECT count(*)FROM link_tag WHERE tag_id = tag.id)。對於那些想知道的人,除非加載關係 –

+0

,否則你不需要' - > with'並且...如果你想...你也可以在一個範圍內做到這一點...'''''''':Tag :: orderByLinkCount() - > PAGINATE(5)'然後在標籤模型創建'scopeOrderByLinkCount'與orderByRaw聲明 –

+0

我相信這應該是'WHERE TAG_ID = tag.id' NOT'WHERE TAG_ID = id' –

0

您還可以使用連接運算符。正如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

36

這對我的作品在Laravel 5.3,使用例如:

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

這種方式查詢和分頁有序很好地工作。

+0

這比接受更好的答案一。 – tremby