我需要将此 MYSQL 查询移植到 Laravel 5.2查询生成器,我不知道如何成功实施逻辑NOT 部分:
SET @in='2017-06-01', @out='2017-06-01';
SELECT
rooms.id,
rooms.name,
reservations.check_in,
reservations.check_out,
reservations.room_id
FROM
rooms
LEFT JOIN
reservations
ON rooms.id = reservations.room_id AND
NOT (
(reservations.check_in < @in AND reservations.check_out < @in)
OR
(reservations.check_in > @out AND reservations.check_out > @out)
)
WHERE reservations.room_id IS NULL
我正在尝试使用查询构建器的原始查询,但它不起作用,我得到调用未定义的方法Illuminate \ Database \ Query \ Expression :: whereNull()错误
$free_rooms = Room
::select('rooms.id', 'rooms.name')
->leftJoin('reservations', 'rooms.id', '=', 'reservations.room_id') AND
DB::raw("
NOT (
(reservations.check_in < $request->check_in AND reservations.check_out < $request->check_in)
OR
(reservations.check_in > $request->check_out AND reservations.check_out > $request->check_out)
)
")
->whereNull('reservations.room_id')
->get();
答案 0 :(得分:2)
首先:
->leftJoin('reservations', 'rooms.id', '=', 'reservations.room_id') AND
将AND
解析为PHP运算符 - 而不是SQL!
和
->whereNull('reservations.room_id')
链接在DB::raw(...)
的结果上并导致异常。
第二:您的加入条件可以简化为
ON rooms.id = reservations.room_id
AND reservations.check_out >= @in
AND reservations.check_in <= @out
第三:如果查询的很大一部分是“原始”,最好不要使用查询构建器。用户hydrateRaw()
改为
$rawQuery = "
SELECT
rooms.id,
rooms.name
FROM
rooms
LEFT JOIN
reservations
ON rooms.id = reservations.room_id
AND reservations.check_out >= :check_in
AND reservations.check_in <= :check_out
WHERE reservations.room_id IS NULL
";
$bindings = [
'check_in' => $request->check_in,
'check_out' => $request->check_out
];
$free_rooms = Room::hydrateRaw($rawQuery, $bindings);
请注意,我刚刚简化了保持逻辑的条件。但通常客户可以在另一个结账时(早上)在同一天(下午)办理登机手续。所以条件应该是
AND reservations.check_out > :check_in
AND reservations.check_in < :check_out