Laravel 5 Query Builder ЛОГИЧЕСКОЕ НЕ

Мне нужно перенести этот запрос MYSQL в Laravel 5.2 Query Builder, и я не понимаю, как успешно реализовать часть Логическое НЕ:

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();

person ant0nio    schedule 23.07.2017    source источник
comment
Если ваш запрос слишком сложен для построителя запросов, вы всегда можете использовать hydrateRaw (). Room::hydrateRaw($rawQuery, $bindings)   -  person Paul Spiegel    schedule 23.07.2017
comment
Я получаю ошибку SQLSTATE [HY093]: Недопустимый номер параметра. Вот вставка того, как выглядит мой код: pastebin.com/mQsjMVqV   -  person ant0nio    schedule 23.07.2017


Ответы (1)


Первое:

    ->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
person Paul Spiegel    schedule 23.07.2017