Próbuję dodać warunek za pomocą zapytania JOIN z 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')
);
Wiem, że mogę używać surowych wyrażeń, ale wtedy pojawią się punkty wstrzyknięcia SQL. Wypróbowałem poniższe z Query Builder, ale wygenerowane zapytanie (i oczywiście wyniki zapytania) nie są tym, co zamierzałem:
$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();
Oto zapytanie wygenerowane przez 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
Jak widać, dane wyjściowe zapytania nie mają struktury (szczególnie w zakresie JOIN). Czy można dodać dodatkowe warunki w JOIN?
Jak mogę zbudować to samo zapytanie używając Laravel's Query Builder (jeśli to możliwe). Czy lepiej jest użyć Eloquent, czy powinien pozostać przy DB :: select?
and arrival >= ? and arrival <= ? and departure >= ? and departure <= ?
zamiast tegoAND ( r.arrival between ? and ? OR r.departure between ? and ? )
(proszę zwrócić uwagę naOR
klauzulę). Spowoduje to dodanie dodatkowych wierszy, których nie powinno tam być. Wydaje mi się, że nie jest możliwe wygenerowanie wszystkich typów warunków łączenia za pomocą QB.Możesz powielić te nawiasy w lewym złączeniu:
LEFT JOIN bookings ON rooms.id = bookings.room_type_id AND ( bookings.arrival between ? and ? OR bookings.departure between ? and ? )
jest
->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('')); })
Będziesz wtedy musiał ustawić powiązania później za pomocą "setBindings", jak opisano w tym poście SO: Jak powiązać parametry z surowym zapytaniem DB w Laravel, które jest używane w modelu?
Nie jest ładna, ale działa.
źródło
Jeśli masz jakieś parametry, możesz to zrobić.
$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();
a następnie zwróć zapytanie
zwraca $ wyników;
źródło
Przykład zapytania sql, taki jak ten
LEFT JOIN bookings ON rooms.id = bookings.room_type_id AND (bookings.arrival = ? OR bookings.departure = ?)
Laravel dołącz z wieloma warunkami
->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); }); })
źródło
Używam laravel5.2 i możemy dodawać połączenia z różnymi opcjami, możesz je modyfikować zgodnie z wymaganiami.
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();
źródło
Istnieje różnica między zapytaniami nieprzetworzonymi a standardowymi selekcjami (między metodami
DB::raw
iDB::select
).Możesz robić, co chcesz, używając a
DB::select
i po prostu upuszczając?
symbol zastępczy, podobnie jak w przypadku przygotowanych instrukcji (tak naprawdę to robi).Mały przykład:
$results = DB::select('SELECT * FROM user WHERE username=?', ['jason']);
Drugi parametr to tablica wartości, które zostaną użyte do zastąpienia symboli zastępczych w zapytaniu od lewej do prawej.
źródło
$join->on('winners.year','=',DB::select('?',array('2013'));
ale nie zadziałało.