there is my db structure:
I want to create a search function for searching available rooms. I can't get the ones which are available, which are not booked for those days. I have tried lots of things but till now can't solve this issue. There is my latest code:
function search ($name, $date_in, $date_out) {
$this->db->select('*')->from('Rooms');
$this->db->join('Reservation', 'rooms.roomid = reservation.rsroomId', 'LEFT');
$this->db->like('date_in', $date_in);
$this->db->like('date_out', $date_out);
$this->db->like('roomName', $name);
return $this->db->get()->result_array();
}
Thank You
I am not very familiar with the CodeIgniter way to build a query, but I understand what you want to achieve. The raw query would look something like this:
SELECT Rooms.*
FROM Rooms
LEFT JOIN Reservation
ON Rooms.roomId = Reservation.rsroomId
AND date_in < '$date_out' AND date_out > '$date_in'
WHERE rsId IS NULL;
To select all overlapping reservations in the JOIN ON
condition, you must compare the date_in
of existing reservations with the $date_out
of the desired reservation, and vice versa. If an existing reservation checks out before you want to check in, it does not overlap. If an existing reservation checks in after you want to check out, it does not overlap.
After carefully crafting these JOIN ON
conditions to get the overlapping reservations, the WHERE rsId IS NULL
condition ensures that you get only rooms for which there is no such existing overlapping reservation.
That last part is easy in CodeIgniter, but getting all the three JOIN ON
conditions into $this->db->join()
is going to be messy. The like()
and where()
functions automatically escape your values, but here you need to add this protection against SQL injection manually. Perhaps something like this:
function search ($date_in, $date_out) {
// Ensuring these values are safe in raw SQL:
$date_in = $this->db->escape($date_in);
$date_out = $this->db->escape($date_out);
$joinCondition = 'rooms.roomid = reservation.rsroomId';
$joinCondition .= " AND date_in < $date_out AND date_out > $date_in";
$this->db->select('*')->from('Rooms');
$this->db->join('Reservation', $joinCondition, 'LEFT');
$this->db->where('rsId', NULL);
return $this->db->get()->result_array();
}
An alternative is to put question marks in the raw query, so CodeIgniter can escape your values via query bindings:
function search ($date_in, $date_out) {
$sql = "SELECT Rooms.*
FROM Rooms
LEFT JOIN Reservation
ON Rooms.roomId = Reservation.rsroomId
AND date_in < ? AND date_out > ?
WHERE rsId IS NULL";
$binds = [$date_out, $date_in];
return $this->db->query($sql, $binds)->result_array();
}