2016-07-01 9 views
1

Имея пользователей, компании и сводную таблицу company_user: Как получить компании, отсортированные по количеству пользователей?Laravel Eloquent рассчитывает многие на многие отношения

Следующий запрос - почти это. Только проблема в том, что я просто получаю компании, у которых хотя бы один пользователь. Каждая компания, не имеющая отношения к пользователю, не учитывается.

$companies = Company::->with('users') 
    ->join('company_user', 'companies.id', '=', 'company_user.company_id') 
    ->selectRaw('companies.*, count(*) as `aggregate`') 
    ->groupBy('companies.id') 
    ->orderBy('aggregate', 'desc') 
    ->get(); 

Пример вывода должен быть:

company_1 (users: 4) 
company_2 (users: 2) 
company_3 (users: 0) 
company_4 (users: 0) 

Вывод с выше запроса:

company_1 (users: 4) 
company_2 (users: 2) 

ответ

1

Похоже, некоторые из ваших компаний, удаляются с помощью INNER JOIN. Если да, то вы можете попробовать использовать LEFT JOIN вместе с SUM (подсчитать количество элементов строк), чтобы сохранить отсутствующие данные:

$companies = Company::->with('users') 
    ->leftJoin('company_user', 'companies.id', '=', 'company_user.company_id') 
    ->selectRaw('companies.*, 
       sum(case when company_user.company_id is null then 0 else 1 end) as `aggregate`') 
    ->groupBy('companies.id') 
    ->orderBy('aggregate', 'desc') 
    ->get(); 

Первоначально я также пытался использовать COUNT(), как вы были, но это, казалось, всегда настаивайте на подсчете NULL строк как 1. Вместо этого я переключился на SUM() с выражением CASE, и он отлично работал.

Перейдите по ссылке ниже для работающей демо:

SQLFiddle

+0

Подойдя ближе. Теперь у меня есть '' '' company_1 (пользователей: 4); company_3 (пользователей: 0); company_4 (пользователей: 0); company_2 (пользователи: 2) '' ' – Kristo

+0

@Kristo Но это не ваш желаемый результат? –

+0

company_2 с двумя пользователями не в порядке ... это за компаниями без пользователей – Kristo