J'essaye d'ajouter une condition en utilisant une requête JOIN avec 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')
);
Je sais que je peux utiliser des expressions brutes, mais il y aura des points d'injection SQL. J'ai essayé ce qui suit avec Query Builder mais la requête générée (et évidemment, les résultats de la requête) ne sont pas ce que je voulais:
$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();
Voici la requête générée par 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
Comme vous pouvez le voir, la sortie de la requête n'a pas la structure (en particulier sous la portée JOIN). Est-il possible d'ajouter des conditions supplémentaires dans le cadre du JOIN?
Comment puis-je créer la même requête en utilisant le Générateur de requêtes de Laravel (si possible) Est-il préférable d'utiliser Eloquent, ou devrait-il rester avec DB :: select?
and arrival >= ? and arrival <= ? and departure >= ? and departure <= ?
placeAND ( r.arrival between ? and ? OR r.departure between ? and ? )
(veuillez noter laOR
clause). Cela ajoute des lignes supplémentaires au résultat qui ne devraient pas être là. Je suppose qu'il n'est pas possible de générer tous les types de conditions dans la jointure en utilisant QB.Vous pouvez répliquer ces crochets dans la jointure de gauche:
LEFT JOIN bookings ON rooms.id = bookings.room_type_id AND ( bookings.arrival between ? and ? OR bookings.departure between ? and ? )
est
->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('')); })
Vous devrez ensuite définir les liaisons plus tard en utilisant "setBindings" comme décrit dans cet article SO: Comment lier des paramètres à une requête DB brute dans Laravel qui est utilisée sur un modèle?
Ce n'est pas joli mais ça marche.
la source
Si vous avez des paramètres, vous pouvez le faire.
$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();
puis renvoyez votre requête
retourne $ results;
la source
L'exemple de requête SQL comme celui-ci
LEFT JOIN bookings ON rooms.id = bookings.room_type_id AND (bookings.arrival = ? OR bookings.departure = ?)
Laravel rejoint avec plusieurs conditions
->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); }); })
la source
J'utilise laravel5.2 et nous pouvons ajouter des jointures avec différentes options, vous pouvez modifier selon vos besoins.
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();
la source
Il y a une différence entre les requêtes brutes et les sélections standard (entre les méthodes
DB::raw
etDB::select
).Vous pouvez faire ce que vous voulez en utilisant un
DB::select
et en déposant simplement l'?
espace réservé, comme vous le faites avec des instructions préparées (c'est en fait ce que cela fait).Un petit exemple:
$results = DB::select('SELECT * FROM user WHERE username=?', ['jason']);
Le deuxième paramètre est un tableau de valeurs qui sera utilisé pour remplacer les espaces réservés dans la requête de gauche à droite.
la source
$join->on('winners.year','=',DB::select('?',array('2013'));
mais je n'ai pas fonctionné.