Laravel Query Builder에서 JOIN 쿼리를 사용하여 조건을 추가하려고합니다.
<?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 삽입 지점이있을 것입니다. 쿼리 작성기로 다음을 시도했지만 생성 된 쿼리 (그리고 분명히 쿼리 결과)가 의도 한 것이 아닙니다.
$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를 유지해야합니까?
답변
$results = DB::table('rooms')
->distinct()
->leftJoin('bookings', function($join)
{
$join->on('rooms.id', '=', 'bookings.room_type_id');
$join->on('arrival','>=',DB::raw("'2012-05-01'"));
$join->on('arrival','<=',DB::raw("'2012-05-10'"));
$join->on('departure','>=',DB::raw("'2012-05-01'"));
$join->on('departure','<=',DB::raw("'2012-05-10'"));
})
->where('bookings.room_type_id', '=', NULL)
->get();
laravel의 조인에 between 절을 추가 할 수 있는지 확실하지 않습니다.
메모:
DB::raw()
Laravel은 따옴표를 다시 넣지 않도록 지시합니다.- 조인 메서드에 클로저를 전달하면 더 많은 조인 조건을
on()
추가하고AND
조건orOn()
을 추가하며OR
조건 을 추가 할 수 있습니다.
답변
왼쪽 조인에서 이러한 대괄호를 복제 할 수 있습니다.
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(''));
})
그런 다음이 SO 게시물에 설명 된대로 나중에 “setBindings”를 사용하여 바인딩을 설정해야합니다
. 모델에서 사용되는 라 라벨의 원시 DB 쿼리에 매개 변수를 바인딩하는 방법은 무엇입니까?
예쁘지는 않지만 작동합니다.
답변
매개 변수가있는 경우이를 수행 할 수 있습니다.
$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();
그런 다음 쿼리를 반환하십시오.
$ 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']);
두 번째 매개 변수는 쿼리의 자리 표시자를 왼쪽에서 오른쪽으로 바꾸는 데 사용되는 값의 배열입니다.