I am programming a Hotel Reservation module. Now I have to connect an existing application to get the available rooms on a given range of dates. Please help me in this.
I am here posting the DB schema of the existing app (where the rooms and bookings info were stored).
rooms:
id
room_type
room_count
people
hotel_id
bookings:
id
from
to
name
email
people
dt
hotel_id
bookings_rooms
booking_id
room_id
quantity
I will give 3 inputs
Hotel ID
From Date
To Date
What I need is a list of room_id and max_qty_available
So, rooms aren't actually rooms, they are a type with a count. Does clear up a few things, although by rooms not being seperate entities it is very hard to prevent a change of rooms being eligable.
SELECT r.id, r.room_count - SUM(br.quantity ) AS max_qty_available
FROM rooms r
LEFT JOIN bookings b
ON b.hotel_id = r.hotel_id
AND b.from < <Date END>
AND b.to > <Date START>
LEFT JOIN booking_rooms br
ON br.room_id = r.id
AND br.booking_id = br.id
WHERE r.hotel_id = <Hotel ID>
I`m guessing what some of this parameters are, but here it goes:
Select id as room_id, room_Count as max_qty_available From Rooms Where
id Not in (Select room_id From Bookings_rooms Where booking_id
In (Select id From bookings Where from>=#FromDate And to <=#ToDate And hotel_id=#HotelID)
) And hotel_id = #HotelID
You can replace IN and NOT IN with Exists and Not exists if there is a performance issue. But not sure if Exists are supported in mysql.
Related
I am trying to get unreserved hotel rooms according to a daterange which is given by user.
I have two tables
rooms with columns room_id, roomno
reservations with columns reserv_id, room_id, checkindate, checkoutdate
Im applying this query
$sql = "SELECT DISTINCT roomno
FROM rooms
LEFT JOIN reservation ON rooms.room_id = reservation.room_id
AND
(
(
(reservation.checkindate > '$newreservcheckin')
AND
(reservation.checkindate > '$newreservcheckout')
)
OR
(
(reservation.checkoutdate < '$newreservcheckin')
AND
(reservation.checkoutdate < '$newreservcheckout')
)
)";
$newreservcheckin and $newreservcheckout are date ranges provided by user
Let's say we have rooms with roomno as 100 and 101
now 100 is booked from 9-16-2016 to 9-18-2016
and 100 is also booked from 9-27-2016 to 9-29-2016
and room 101 is unreserved(meaning it has no record in reservation table)
Suppose if user gives dates 9-26-2016 to 9-30-2016 query will ignore the room no 100 entry which is from 9-27-2016 to 9-29-2016 but will show the room no 100 with dates from 9-16-2016 to 9-18-2016 and will show 101 room
How to mold the query so that it may not give the same room but the one with different dates?
You need to select the rooms which are either (A) Not booked or (B) Booked but outside the range you are querying for, below query should work:
select no from room r
where not exists (
select id from reservation where room_id = r.id)
union
select no from room r
where r.id not in (
select distinct room_id from reservation
where
checkindate between '2016-09-20' and '2016-09-22'
OR
checkoutdate between '2016-09-20' and '2016-09-22'
)
Here is the SQL Fiddle.
You can join every reservation that overlaps with new checking dates and select those rooms which have nothing to join. In my query I expect that new guests can checkin at the same date when previous would checkout. If not - change "<" to "<=" and ">" to ">=".
SELECT
r.roomno
FROM
rooms r
LEFT JOIN
reservations res ON res.room_id = r.room_id
AND res.checkindate < '$newreservcheckout'
AND res.checkoutdate > '$newreservcheckin'
WHERE res.reserv_id IS NULL
I am new to PHP and I am trying to develop a student management system with two tables:
1.student_details_tbl
2.student_fees_tbl
In student_details_tbl all details of students are saved and in the student_fees_tbl table, details of which students have paid their month's fees are saved.
My problem is that I wanted a list of students who have not paid their fees for the user selected month.
student_detais_tbl has the following fields:
id student_id name age address contact image
student_fees_tbl has the following fields:
id student_id month type amount
TRY this query ...
SELECT *
FROM student_detais_tbl
WHERE id NOT IN( SELECT A.student_id
FROM student_fees_tbl A
JOIN student_detais_tbl B
ON A.student_id = B.id AND A.month='Month'
)
SELECT *
FROM student_details_tbl
WHERE student_id NOT IN(SELECT student_id from student_fees_tbl where month='Month')
Is there any problem with this query
I have some problems to compare two of my tables. Usually I show my attempt how to solve a problem but here I do not know what to do. Normally, I do it in php. So i get all the information from 2 tables and then compare. But I would like to do it in MySQL. I hope you can help.
The first table, is my transactions table. This is the place where people have used their cards in restaurants.
The second table is my booking table. This is the place where people book reservations in restaurant.
I want to compare these tables, so i can get those who has NOT used their reservation
Transaction mySQL
SELECT t.*, em.* FROM transactions as t
left join exp_members as em on (t.cardid-10000000 = em.member_id)
left JOIN exp_member_data emd on em.member_id = emd.member_id ORDER BY t.created DESC
Transaction Table.
Trans_ID TransactionTime Name Restaurant
1852 2013-04-08 12:45:21 Christian La Canton
1851 2013-04-08 12:41:00 Zaz Parken
Booking mySQL
SELECT b.* from exp_menucard_booking as b;
Booking Table:
ID BookingTime Name NumberOfPeople Restaurant
270 2013-04-09 14:45:00 Christian 2 La Canton
269 2013-04-08 12:17:00 Toby 4 La Raz
As you can se, Toby from Booking table has not used his card (transaction tabel). How can i get him out of my tabel.
If you want to select all persons, who have already booked (there is an entry in booking table) but do not have an entry in the Transaction Table you could try this query:
SELECT *
FROM `Booking` B
WHERE NOT EXISTS (
SELECT *
FROM `Transaction` T
WHERE T.name = B.name
);
BTW it would be better, if you used some User_ID instead of name to identify the persons
This is how you can select all the records that didn't use the booking. It's called an excluding left join or left exclude join. http://www.magecorner.com/mysql-joins-explained/
I'm not sure if this would be faster than WHERE NOT EXISTS, but considering that has a subquery, I think this is faster.
SELECT emb.*
FROM exp_menucard_booking emb
LEFT JOIN transactions t
ON (
t.Name = emb.Name AND
t.Restaurant = emb.Restaurant
)
WHERE t.Trans_ID IS NULL
SELECT * FROM Booking WHERE NAME NOT IN (SELECT NAME FROM Transaction );
I am trying to retrieve schedules for each team based on my table below, but I am having some trouble getting the team names to display. Here are my tables:
TEAM
(team_id,
team_name,
team_mascot,
etc.)
GAME
(game_id,
game_date,
game_home_team,
game_visitor_team,
game_home_score,
game_visitor_score,
game_complete)
Here is my current query. I am able to get the team's id values with this but I need the team names as id values won't do me much good.
SELECT game_home_team, game_visitor_team, game_date
FROM game
INNER JOIN team home ON home.team_id = game_home_team
INNER JOIN team visitor ON visitor.team_id = game_visitor_team
WHERE game_home_team = ?
OR game_visitor_team = 6
ORDER BY game_date ASC;
How can I retrieve the team names with this query and also display a result such as W or L depending on the score for the game? Thanks so much in advance.
SELECT
home.team_name AS home_team,
visitor.team_name AS visitor_team,
game_date,
IF(
game_home_score = game_visitor_score,
'Tie',
IF(
game_home_score > game_visitor_score,
'Hometeam',
'Visitorteam'
)
) AS Winner
FROM game
INNER JOIN team home ON home.team_id = game_home_team
INNER JOIN team visitor ON visitor.team_id = game_visitor_team
WHERE game_home_team = ?
OR game_visitor_team = 6
ORDER BY game_date ASC;
select game_home_team, home.team_name AS homename,
game_visitor_team, visitor.team_name AS visitorname
etc...
I have above mysql table with available dates and prices. Second table includes room details. How can I join two tables to get available rooms between two dates and not get duplicate content.
This is hard to come up with a complete answer for you here, as you are only showing us the table which contains the bookings - we cannot know what range of rooms are available.
SQL which returns the room_id's for rooms which are booked for at least part of the selected period could be:
SELECT `room_id` , COUNT(*)
FROM `bookings`
WHERE `dt` BETWEEN "[start date]" AND "[end date]"
GROUP BY `room_id`;
If you had a table of rooms (rather than bookings), it would be possible for you to return a list of any rooms not booked during that period with:
SELECT `id`
FROM `rooms`
WHERE `id` NOT IN (
SELECT DISTINCT( `room_id` )
FROM `bookings`
WHERE `dt` BETWEEN "[start date]" AND "[end date]"
);
AMENDMENT
Based on the feedback by OP, the assumptions are now:
The table contains details of rooms which are available for a period starting on the date in column dt and ending the following day (ie hotel rooms)
The query should return any rooms which are available for the entirity of the period entered (so only rooms which are available from DAY A to DAY B will be returned.
As such, the amended code is:
SELECT room_id
FROM available_rooms
WHERE dt BETWEEN "[start date]" AND DATE_SUB("[end date]",INTERVAL 1 DAY)
GROUP BY room_id
HAVING COUNT(*)=ABS(DATEDIFF("[start date]","[end date]"));
SELECT available.* , rooms.* FROM available, rooms
WHERE available.room_id = rooms.room_id AND
available.dt BETWEEN '2005-01-01' AND '2005-12-31'
Assuming the table you showed us is called rooms_dates with two other tables rooms and room_details:
select room.id, room_details.xxxxxxx from rooms
inner join room_details on rooms.id = room_details.room_id
where rooms.id in
(
select distinct room_id from rooms_dates
where dt >= 'xxxx-xx-xx' and dt <= 'yyyy-yy-yy'
);