I need to do a very complex search
Context: I have 3 tables: rooms, reservation, and room_reservation. The first one have all info of the rooms in a hotel, the second have info of all reservation and the third is because a reservation have multiple rooms.
I need know what rooms are available in a expecific date, I really close, I need that if at least one data does not match the condition of the search then the related room is not shown.
This is my query:
SELECT DISTINCT hab.* FROM habitacion hab
LEFT OUTER JOIN habitacion_reserva habr ON habr.id_habitacion = hab.id
LEFT OUTER JOIN reserva res ON res.id = habr.id_reserva
WHERE hab.tipo = 1
AND (((( '2018-06-10' not between res.fecha_ingreso and res.fecha_salida) AND ( '2018-06-17' not between res.fecha_ingreso and res.fecha_salida))
OR (res.fecha_ingreso is null OR res.fecha_salida is null)) OR ((( '2018-06-09' between res.fecha_ingreso and res.fecha_salida) OR ( '2018-06-17' between res.fecha_ingreso and res.fecha_salida)) AND res.estado = 4))
In theory the query works but when I have many reservation, the query simply return all rooms.
Try something like this (simplified)
Select * FROM rooms
LEFT JOIN room_reservation ON (rooms.id = rooms_reservation.id)
LEFT JOIN reservations ON (rooms_reservation.id = reservation.id)
reservation
WHERE 1=1
...
AND whateverfield = 1
....
AND ('2018-06-09' NOT BETWEEN reservation.start AND reservation.end)
AND ('2018-06-17' NOT BETWEEN reservation.start AND reservation.end)
GROUP BY rooms
Related
I have a table that looks like this:
For each COMPANY there are multiple NATURAL_PERSON_ID, every NATURAL_PERSON have a date in which an audit was performed FECHA_DE_REPORTE and as a company there is a date in which the first loan was give to that company.
What I want is to select for each NATURAL_PERSON all the FOLIO_CONSULTA whose FECHA_DE_REPORTE is less or equal to FIRST_LOAN (the date in which the first loan was given for that company) Then I need to find the MAX date among each group and keep al the information (the whole row) for the value that fulfills all these conditions, and all this for each NATURAL_PERSON
So for this example the result I expected is all the information of the second row since this is the MAX() of FECHA_DE_REPORTE by COMPANY AND NATURAL_PERSON.
I have tried:
SELECT NPC.COMPANY_ID
,NPC.NATURAL_PERSON_ID
,NPS.DIGITAL_SIGNATURE_ID
,CDC.FOLIO_CONSULTA
,CDC.FECHA_DE_REPORTE
,FIRST_LOAN.FIRST_LOAN
,MAX(CDC.FECHA_DE_REPORTE) MAX_FOLIO_CONSUTA
FROM KONFIO.NATURAL_PERSON_COMPANY NPC
LEFT JOIN KONFIO.NATURAL_PERSON_SIGNATURE NPS ON NPS.NATURAL_PERSON_ID = NPC.NATURAL_PERSON_ID
JOIN KONFIO.CDC_RESPONSE CDC ON CDC.DIGITAL_SIGNATURE_ID= NPS.DIGITAL_SIGNATURE_ID
JOIN
(
SELECT CAPP.COMPANY_ID
,MIN(LOAN.DOCUMENTATION_DATE) FIRST_LOAN
FROM KONFIO.COMPANY_APPLICATION CAPP
JOIN KONFIO.LOAN ON LOAN.APPLICATION_ID = CAPP.APPLICATION_ID
GROUP BY CAPP.COMPANY_ID) FIRST_LOAN ON FIRST_LOAN.COMPANY_ID = NPC.COMPANY_ID
WHERE CDC.FECHA_DE_REPORTE <= FIRST_LOAN.FIRST_LOAN
AND NPC.COMPANY_ID IN (1033)
GROUP BY NPC.COMPANY_ID, NPC.NATURAL_PERSON_ID
but it retrieves the first value that finds so the FOLIO_CONSULTA does not correspond to the FOLIO_CONSULTA of the MAX() FECHA_DE_REPORTE
Any help would be appreciated
You should join the subquery for MAX(FECHA_DE_REPORTE) on table CDC_RESPONSE
SELECT NPC.COMPANY_ID
,NPC.NATURAL_PERSON_ID
,NPS.DIGITAL_SIGNATURE_ID
,CDC.FOLIO_CONSULTA
,CDC.FECHA_DE_REPORTE
,FIRST_LOAN.FIRST_LOAN
,T.MAX_FOLIO_CONSUTA
FROM KONFIO.NATURAL_PERSON_COMPANY NPC
INNER JOIN (
SELECT DIGITAL_SIGNATURE_ID
, MAX(FECHA_DE_REPORTE) MAX_FOLIO_CONSUTA
FROM KONFIO.CDC_RESPONSE
GROUP BY DIGITAL_SIGNATURE_ID
) T ON T.DIGITAL_SIGNATURE_ID = NPS.DIGITAL_SIGNATURE_ID
AND T.MAX_FOLIO_CONSUTA = CDC.FECHA_DE_REPORTE
LEFT JOIN KONFIO.NATURAL_PERSON_SIGNATURE NPS ON NPS.NATURAL_PERSON_ID = NPC.NATURAL_PERSON_ID
JOIN KONFIO.CDC_RESPONSE CDC ON CDC.DIGITAL_SIGNATURE_ID= NPS.DIGITAL_SIGNATURE_ID
JOIN
(
SELECT CAPP.COMPANY_ID
,MIN(LOAN.DOCUMENTATION_DATE) FIRST_LOAN
FROM KONFIO.COMPANY_APPLICATION CAPP
JOIN KONFIO.LOAN ON LOAN.APPLICATION_ID = CAPP.APPLICATION_ID
GROUP BY CAPP.COMPANY_ID) FIRST_LOAN ON FIRST_LOAN.COMPANY_ID = NPC.COMPANY_ID
WHERE CDC.FECHA_DE_REPORTE <= FIRST_LOAN.FIRST_LOAN
AND NPC.COMPANY_ID IN (1033)
GROUP BY NPC.COMPANY_ID, NPC.NATURAL_PERSON_ID
...... missing part
I have 3 tables, the first table is the account_has_account1 where i store the relation between accounts and it's columns are account_id, account_id1, status where account_id is the account doing following to account_id1 and status is an enum type with values active, inactive where active indicates if the account is actually following, if it's inactive, then account stopped following.
the second table is named account_has_photos which i store the photos one account has stored in the database, so it's columns are account_id, photos_id, so i need this table to get all photos from one account which another account is following.
But all these have messages posted on them, and here is where the 3rd table comes which is named photos_has_message_photos, from this table i only need a count of all posted messages in one photo, the columns are photos_id, message_photos_id
for now my query is this:
SELECT account_has_photos.photos_id as id, "photos" as type, account_has_photos.update_at, account_has_photos.account_id
FROM account_has_account1
JOIN account_has_photos
ON (account_has_photos.account_id = account_has_account1.account_id1 AND account_has_photos.type_id = 17)
WHERE account_has_account1.account_id = 7 AND account_has_account1.`status` = "Active"
it shows all photos from accounts on which account id 7 is following, but on my attempts on getting the total messages have failed, i thought on doing an INNER JOIN like this:
INNER JOIN (
SELECT photos_has_message_photos.photos_id, count(photos_has_message_photos.photos_id) as total
FROM photos_has_message_photos
) posts
ON(posts.photos_id = account_has_photos.photos_id)
and then i select from main posts.total, but it does not show any row, not even the photos, the result is empty at this point and i have no idea why and what to do.
the complete query is like this:
SELECT account_has_photos.photos_id as id, "photos" as type, account_has_photos.update_at, account_has_photos.account_id, posts.total
FROM account_has_account1
JOIN account_has_photos
ON (account_has_photos.account_id = account_has_account1.account_id1 AND account_has_photos.type_id = 17)
INNER JOIN (
SELECT photos_has_message_photos.photos_id, count(photos_has_message_photos.photos_id) as total
FROM photos_has_message_photos
) posts
ON(posts.photos_id = account_has_photos.photos_id)
WHERE account_has_account1.account_id = 7 AND account_has_account1.`status` = "Active"
again, i only need a total of rows which are messages from each photos found
Try this query updated inner select
SELECT ahp.photos_id as id, "photos" as type, ahp.update_at, ahp.account_id,posts.total
FROM account_has_account1
JOIN account_has_photos
ON (ahp.account_id = account_has_account1.account_id1 AND ahp.type_id = 17) INNER JOIN (
SELECT phmp.photos_id, count(*) as total FROM photos_has_message_photos GROUP BY phmp.photos_id
) posts
ON(posts.photos_id = ahp.photos_id) WHERE account_has_account1.account_id = 7 AND account_has_account1.`status` = "Active"
I'm trying to get my head around this SQL question:
A database for a hotel chain contains the following tables:
Hotel(HotelNo, HotelName, City)
Room(RoomNo, HotelNo, Type, Price)
Booking(HotelNo, GuestNo, DateFrom, DateTo, RoomNo)
Guest(GuestNo, GuestName, GuestAddress)
I want to List the details of all rooms at the Grosvenor Hotel,including the name of the guest staying in the room, if the room is occupied.
I'm okay with joining 2 tables in SQL but I don't know how to go about joining 4 tables.
My attempt would probably be:
SELECT Room.*, Guest.GuestName
FROM Room
INNER JOIN Hotel, Booking, Guest
ON Hotel.HotelName = "Grosvenor Hotel", Hotel.HotelNo = Room.HotelNo, Booking.GuestNo = Guest.GuestNo;
I think that's completely wrong but anyway, hopefully someone knows what I should be doing. Thanks in advance
The correct syntax is:
SELECT Room.*, Guest.GuestName
FROM Room
INNER JOIN Hotel on Hotel.HotelNo = Room.HotelNo,
inner join Booking on Booking.hotelno= Hotel.HotelNo
inner join Guest on Booking.GuestNo = = Guest.GuestNo
where Hotel.HotelName = "Grosvenor Hotel"
Try this :
select g.roomno, g.guestname
from hotel h join room r on h.hotelno = r.hotelno
join booking b on b.hotelno=r.hotelno
join guest g on g.guestno=b.guestno
where h.hotelname='Grosvenor Hotel';
you can also try this .. It Will help You
SELECT Room.*, Guest.GuestName FROM Room
INNER JOIN Hotel on Hotel.HotelNo = Room.HotelNo,
join Booking on Booking.HotelNo= Hotel.HotelNo
join Guest on Booking.GuestNo = Guest.GuestNo
where Hotel.HotelName = "Grosvenor Hotel"
i am developing a PHP/MYSQL search module, where i have to search tables based on many different criteria, i have some 11 tables, and i have used multiple joins to create one single MySQL query and based on WHERE clause i intend to search for specific records, here is the MYSQL Query that i am using.
SELECT
prop.id,
prop.serial,
prop.title,
prop.rating,
prop.addDate,
prop.approve,
prop.status,
prop.user_id as userId,
user_det.email as email,
user_det.name as name,
prop.area_id as areaId,
area.name as areaName,
area.zipCode as zipCode,
area.city_id as cityId,
city.name as cityName,
city.state_id as stateId,
state.name as stateName,
state.country_id as countryId,
country.name as countryName,
prop.subCategory_id as subCategoryId,
subCat.name as subCategoryName,
subCat.category_id as categoryId,
cat.name as categoryName,
prop.transaction_id as transactionId,
trans.name as transactionName,
price.area as landArea,
price.price as priceSqFt,
price.total_price as totalPrice,
features.bedroom,
features.bathroom,
features.balcony,
features.furnished,
features.floorNum,
features.totalFloor
FROM properties prop
LEFT JOIN user_details user_det ON (prop.user_id = user_det.user_id)
LEFT JOIN areas area ON (prop.area_id = area.id)
LEFT JOIN cities city ON (area.city_id = city.id)
LEFT JOIN states state ON (city.state_id = state.id)
LEFT JOIN countries country ON (state.country_id = country.id)
LEFT JOIN subCategories subCat ON (prop.subCategory_id = subCat.id)
LEFT JOIN categories cat ON (subCat.category_id = cat.id)
LEFT JOIN transactions trans ON (prop.transaction_id = trans.id)
LEFT JOIN prop_prices price ON (price.property_id = prop.id)
LEFT JOIN prop_features features ON (features.property_id = prop.id)
although all works well here, i have a situation where i have a table called prop_amenities below are the content of this table.
as the table above have multiple property_id if i query it using JOINS then mostly it will return duplicate records or single record omitting others depending on the type of JOIN i use. so instead i would like to deal it this way.
use the table prop_amenities to only deal with conditions not to return the result.
for example i am searching for a property with amenity id 1,5,9,17 and 24, then it should check if all the records exist in the prop_amenities table, i.e 1,5,9,17 and 24 in this case. and return the appropriate records with all above selected columns.
i am clueless on dealing this situation using MySQL. how do i go on this?
thank you..
You said "check if all the records exist in the prop_amenities table" and that's the key word here.
SELECT ...
FROM properties AS prop
LEFT JOIN ...
WHERE EXISTS (SELECT 1 FROM prop_amenities AS pa WHERE pa.property_id = prop.property_id AND pa.amenity_id = 7);
I have entires, equipments, brands, times and seasons.
entries:
id
time
equipment_1
equipment_2
equipments:
id
id_brand
brands:
id
name
times:
id
id_season
seasons:
id
name
My actual SQL query is:
SELECT entries.*, times.id_season AS id_season
FROM entries, seasons
WHERE entries.time = times.id
But in the final query I need the next information that I don't know how to obtain it:
The name for each entries.equipment_ as equipment_1_name and equipment_2_name which is set in brands.name.
The name of the season as season_name.
Thank you in advance!
Assuming you have normalized data. This avoid costly cartesian joins. I never use cartesian joins myself, although there are some cases where they are useful. Not here, though.
SELECT
entries.*,
times.id_seasons AS id_season,
b1.name AS equipment_1_name,
b2.name AS equipment_2_name,
seasons.name AS season_name
FROM entries
LEFT JOIN equipments AS equipments_1
ON equipments_1.id = entries.equipment_1
LEFT JOIN brands AS brands_1
ON brands_1.id = equipments_1.id_brand
LEFT JOIN equipments AS equipments_2
ON equipments_2.id = entries.equipment_2
LEFT JOIN brands AS brands_2
ON brands_2.id = equipments_2.id_brand
LEFT JOIN times
ON times.id = entries.time
LEFT JOIN seasons
ON seasons.id = times.id_season;