2013-07-01 3 views
14

Я пытаюсь выбрать все результаты из одной таблицы и объединиться с другой таблицей, когда совпадает идентификатор пользователя.Laravel 4 Query Builder: LEFT JOIN ... AND ... query

У меня есть три таблицы: работает, пользователи и сводная таблица run_user. Я хочу выбрать все результаты из «прогонов» и дополнительных столбцов в сводной таблице («завершенные», «липкие», «last_tested» и «трудности»), но только извлекать данные из run_user для текущего пользователя.

В сыром SQL я сумел сделать это с помощью LEFT JOIN с оператором И:

SELECT 
runs.startpoint, 
runs.startpostcode, 
runs.endpoint, 
runs.endpostcode, 
run_user.completed, 
run_user.sticky, 
run_user.last_tested, 
run_user.difficulty 
FROM runs 
LEFT JOIN run_user ON run_user.run_id=runs.id AND run_user.user_id = '2' 

Любые предложения, как сделать это с помощью Query Builder? Я могу сделать LEFT JOIN в Laravel 4, но не могу понять, как совместить это с инструкцией AND.

Любая помощь приветствуется.

Спасибо!

ответ

1

В Laravel 4 вы можете сделать это, используя запрос Eloquent. Я предполагаю, что вы знаете о взаимоотношениях с людьми и знаете, как создавать модели. Для вашего запроса он должен быть

RunUser::where('user_id',$id)->leftjoin('runs','runs.id','=','run_user.run_id')->first(); 

Примечание RunUser является моделью для run_user таблицы.

+0

Спасибо за ваше предложение. К сожалению, у меня такая же проблема, используя предложение «где». Это отлично работает для строк, где таблица run_user имеет запись для запуска, но не получает все прогоны. – user2324369

+0

попробуйте изменить на 'Runs :: where ('id', $ id) -> leftjoin ('run_user', 'run_user.run_id', '=', 'работает.id ') -> first(); ' –

30

Как вы просили, это то, как вы могли бы сделать запрос с построитель запросов:

DB::table('runs') 
     ->leftJoin('run_user', function($join) 
     { 
      $join->on('run_user.run_id', '=', 'runs.id') 
      ->on('run_user.user_id', '=', '2'); 
     }) 
     ->get(); 

Но РЕГИСТРИРУЙТЕСЬ заявление выглядит немного странно, вы, вероятно, хотите, чтобы превратить это в нормальный WHERE (если не вам имеют очень специфическую причину для фильтрации непосредственно в предложении JOIN).

DB::table('runs')->join('run_user', 'run_user.run_id', '=', 'runs.id')->where('run_user.user_id', '=', '2')->get(); 

Docs: http://laravel.com/docs/queries#joins

+0

Спасибо, похоже, что условие' andOn 'не работает с версией 4 (http://laravel.com/api/class-Illuminate.Database.Query.JoinClause. html) – user2324369

+0

Вы правы, извините. Я отредактировал свой ответ, вы можете сделать -> on() -> on(), чтобы делать AND в JOIN. –

+4

Создание соединения в поле, а затем где не то же самое, что 2 условия для соединения. –

6

В случае, если кто-то интересно, я получил эту работу, используя DB :: сырец на одном из параметров LeftJoin:

DB::table('runs') 
    ->leftjoin('run_user', 'runs.id','=', 
     DB::raw('run_user.run_id AND run_user.user_id = ' . $user->id)) 
    ->get(); 

Это не так 'красноречивый', как я «Как бы это ни было, но без рабочего состояния» и «Это», кажется, это единственный способ, если вы хотите добавить AND в LEFT JOIN.

Если кто-нибудь может предложить более аккуратный способ, я бы с удовольствием узнал!

Благодаря

+2

Вы можете сделать это с помощью -> leftJoin() и закрытия с -> on() -> on(), как я показал в своем ответе, что намного чище. Также ваша двойная статья JOIN должна действительно быть ГДЕ. –

+0

Я думаю, что это решение лучше. – Sky

0

Провидентные и пользователь Таблица регистрации и получить идентификатор для всех деталей.

$return = DB::table(config::get('databaseconstants.TBL_USER')) 
      ->leftjoin('inex_pf_details', 'inex_users.id', '=', 'inex_pf_details.pf_user_id') 
      ->select('inex_pf_details.*','inex_users.*') 
      ->where('inex_pf_details.id', $id) 
      ->first(); 
    return $return; 
0

использование этого

DB::table('runs')->select('runs.startpoint','runs.startpostcode','runs.endpoint','runs.endpostcode','run_user.completed','run_user.sticky','run_user.last_tested','run_user.difficulty') 
    ->leftJoin('run_user', function($join) 
    { 
     $join->on('run_user.run_id', '=', 'runs.id') 
     ->where('run_user.user_id', '2'); 
    }) 
    ->get(); 
0

Здесь должны работать:

DB::table('runs') 
     ->leftJoin('run_user', function($join) use ($user_id) 
     { 
      $join->on('run_user.run_id', '=', 'runs.id') 
      ->where('run_user.user_id', '=', $user_id); 
     }) 
     ->get(); 
+1

Не могли бы вы объяснить, как это работает или что он должен делать? –