Я пытаюсь добавить условие, используя запрос JOIN с Laravel Query Builder.
<?php
$results = DB::select('
SELECT DISTINCT
*
FROM
rooms
LEFT JOIN bookings
ON rooms.id = bookings.room_type_id
AND ( bookings.arrival between ? and ?
OR bookings.departure between ? and ? )
WHERE
bookings.room_type_id IS NULL
LIMIT 20',
array('2012-05-01', '2012-05-10', '2012-05-01', '2012-05-10')
);
Я знаю, что могу использовать Raw Expressions, но тогда будут точки SQL-инъекций. Я пробовал следующее с Query Builder, но сгенерированный запрос (и, очевидно, результаты запроса) не то, что я планировал:
$results = DB::table('rooms')
->distinct()
->leftJoin('bookings', function ($join) {
$join->on('rooms.id', '=', 'bookings.room_type_id');
})
->whereBetween('arrival', array('2012-05-01', '2012-05-10'))
->whereBetween('departure', array('2012-05-01', '2012-05-10'))
->where('bookings.room_type_id', '=', null)
->get();
Это сгенерированный запрос Laravel:
select distinct * from `room_type_info`
left join `bookings`
on `room_type_info`.`id` = `bookings`.`room_type_id`
where `arrival` between ? and ?
and `departure` between ? and ?
and `bookings`.`room_type_id` is null
Как видите, выходные данные запроса не имеют структуры (особенно в области JOIN). Можно ли добавить дополнительные условия под JOIN?
Как я могу создать тот же запрос с помощью Laravel Query Builder (если возможно). Лучше использовать Eloquent или следует остаться с DB :: select?
and arrival >= ? and arrival <= ? and departure >= ? and departure <= ?
вместо него теперь используется условие соединенияAND ( r.arrival between ? and ? OR r.departure between ? and ? )
(обратите внимание на этоOR
предложение). Это добавляет к результату дополнительные строки, которых там не должно быть. Я предполагаю, что с помощью QB невозможно сгенерировать все типы условий при объединении.Вы можете скопировать эти скобки в левом соединении:
LEFT JOIN bookings ON rooms.id = bookings.room_type_id AND ( bookings.arrival between ? and ? OR bookings.departure between ? and ? )
является
->leftJoin('bookings', function($join){ $join->on('rooms.id', '=', 'bookings.room_type_id'); $join->on(DB::raw('( bookings.arrival between ? and ? OR bookings.departure between ? and ? )'), DB::raw(''), DB::raw('')); })
Затем вам нужно будет установить привязки позже, используя «setBindings», как описано в этом сообщении SO: Как привязать параметры к необработанному запросу БД в Laravel, который используется в модели?
Это некрасиво, но работает.
источник
Если у вас есть параметры, вы можете это сделать.
$results = DB::table('rooms') ->distinct() ->leftJoin('bookings', function($join) use ($param1, $param2) { $join->on('rooms.id', '=', 'bookings.room_type_id'); $join->on('arrival','=',DB::raw("'".$param1."'")); $join->on('arrival','=',DB::raw("'".$param2."'")); }) ->where('bookings.room_type_id', '=', NULL) ->get();
а затем верните свой запрос
return $ results;
источник
Пример запроса sql, подобный этому
LEFT JOIN bookings ON rooms.id = bookings.room_type_id AND (bookings.arrival = ? OR bookings.departure = ?)
Laravel присоединяется с несколькими условиями
->leftJoin('bookings', function($join) use ($param1, $param2) { $join->on('rooms.id', '=', 'bookings.room_type_id'); $join->on(function($query) use ($param1, $param2) { $query->on('bookings.arrival', '=', $param1); $query->orOn('departure', '=',$param2); }); })
источник
Я использую laravel5.2, и мы можем добавлять соединения с различными параметрами, которые вы можете изменить в соответствии с вашими требованиями.
Option 1: DB::table('users') ->join('contacts', function ($join) { $join->on('users.id', '=', 'contacts.user_id')->orOn(...);//you add more joins here })// and you add more joins here ->get(); Option 2: $users = DB::table('users') ->join('contacts', 'users.id', '=', 'contacts.user_id') ->join('orders', 'users.id', '=', 'orders.user_id')// you may add more joins ->select('users.*', 'contacts.phone', 'orders.price') ->get(); option 3: $users = DB::table('users') ->leftJoin('posts', 'users.id', '=', 'posts.user_id') ->leftJoin('...', '...', '...', '...')// you may add more joins ->get();
источник
Есть разница между необработанными запросами и стандартными выборками (между
DB::raw
иDB::select
методы).Вы можете делать то, что хотите,
DB::select
просто вставив?
заполнитель, так же, как вы делаете с подготовленными операторами (это фактически то, что он делает).Небольшой пример:
$results = DB::select('SELECT * FROM user WHERE username=?', ['jason']);
Второй параметр - это массив значений, который будет использоваться для замены заполнителей в запросе слева направо.
источник
$join->on('winners.year','=',DB::select('?',array('2013'));
но не сработало.