这是一个酒店代理的示例程序,他从各个酒店获得合同,并允许客户搜索和预订他与之签订合同的酒店(从而获得一些利润)。这是我的表格模式。
CONTRACT (contract_id, hotel_id, valid_from, valid_to)
ROOM (room_type, hotel_id, contract_id, price, max_adults_allowed, avail_rooms)
HOTEL (hotel_id, hotel_name, location)
用于搜索,界面如hotels.com;即,例如,顾客可以指定它为“1个房间有2个成人”和“1个房间2个成人和1个房间3个成人”。
到目前为止,这是我的SQL查询,
select h.name, h.location, r.type, r.price FROM HOTEL h, ROOM r, CONTRACT c
WHERE c.contract_id = r.contract_id and c.hotel_id = h.hotel_id --table joining
AND 'requested room lies within the contract valid period' --check in and check out dates comparison
AND 'h.location is the user specified location' --requested location
........
我无法将房间搜索详情(如上所述)整合到此查询中。有人可以帮我写sql查询以包含房间规格。我正在使用SQL Server。提前谢谢。
答案 0 :(得分:1)
假设您已经解析了“自然语言”输入,请通过max_adults对请求进行分组,然后查询每个单独的类型;例如'2个房间1个成人和3个房间2个成人'发出两个单独的查询(max_adults = 1,avail_rooms = 2)和(max_adults = 2,avail_rooms = 3)
select h.name, h.location, r.type, r.price, r.room_id FROM HOTEL h, ROOM r, CONTRACT c
WHERE c.contract_id = r.contract_id and c.hotel_id = h.hotel_id
AND c.valid_from >= ? AND c.valid_to <= ? AND h.location = ?
AND r.max_adults = ? AND r.avail_rooms >= ?
请注意,这只会找到max_adults的完全匹配,并且不会为您提供“预订”房间的选项。如果您想允许客户预订大房间(并相应地支付,而不填写),您可以使用以下策略:首先尝试原始查询,然后搜索更大的房间(通过添加“人工客人”)。
例如,如果原始请求是'1 triple,1 double,1 single',请先尝试,然后'1 triple 2 double',然后'2 triples 1 double',然后'3 triples'。对于每个“已修改”的查询,请使用上面的SQL。第一个成功的将是客户最便宜的选择。
即使这涉及多个SQL事务,每个事务都有简单的连接,并且可能比复杂的语句更快。
如果您有更多控制权,您可能会更改架构以分别考虑每个房间:
ROOM (room_id, room_type, hotel_id, contract_id, price, max_adults_allowed)
BOOKING (room_id, checkin, checkout)
答案 1 :(得分:1)
此脚本检索只有必需房间的酒店。如果酒店只有一个必要的房间,则不包括酒店。
更新15.01.2013
IF OBJECT_ID('tempdb.dbo.#RoomParams') IS NOT NULL DROP TABLE dbo.#RoomParams
SELECT SUM(rooms) AS rooms, adults
INTO dbo.#RoomParams
FROM (VALUES(1, 2), -- 1 room with 2 adults
(1, 2), -- 1 room with 2 adults
(1, 3)) -- 1 room with 3 adults
p(rooms, adults)
GROUP BY adults
;WITH cte AS
(
SELECT h.hotel_id, h.hotel_name, h.location, r.room_type, r.price,
SUM(avail_rooms) OVER (PARTITION BY h.hotel_id, r.max_adults_allowed) AS cnt,
r.max_adults_allowed
FROM CONTRACT c JOIN ROOM r ON c.contract_id = r.contract_id AND c.hotel_id = r.hotel_id
JOIN HOTEL h ON c.hotel_id = h.hotel_id
WHERE c.valid_from >= '20130114' AND c.valid_to <= '20130115' --check in and check out dates comparison
AND h.location IN ('loc4') --requested location
)
SELECT *
FROM cte s
WHERE
NOT EXISTS (
SELECT rp.adults
FROM dbo.#RoomParams rp
EXCEPT
SELECT st.max_adults_allowed
FROM cte st JOIN dbo.#RoomParams r ON st.cnt >= r.rooms AND st.max_adults_allowed = r.adults
WHERE st.hotel_id = s.hotel_id
) AND s.max_adults_allowed IN (SELECT adults FROM dbo.#RoomParams)
SQLFiddle上的演示
如果您想要检索所有至少有一个选项的酒店
IF OBJECT_ID('tempdb.dbo.#RoomParams') IS NOT NULL DROP TABLE dbo.#RoomParams
SELECT rooms, adults
INTO dbo.#RoomParams
FROM (VALUES(1, 2), -- 1 room with 2 adults
(1, 2), -- 1 room with 2 adults
(1, 3)) -- 1 room with 3 adults
p(rooms, adults)
;WITH cte AS
(
SELECT h.hotel_id, h.hotel_name, h.location, r.room_type, r.price,
SUM(avail_rooms) OVER (PARTITION BY h.hotel_id, r.max_adults_allowed) AS cnt,
r.max_adults_allowed
FROM CONTRACT c JOIN ROOM r ON c.contract_id = r.contract_id AND c.hotel_id = r.hotel_id
JOIN HOTEL h ON c.hotel_id = h.hotel_id
WHERE c.valid_from >= '20130114' AND c.valid_to <= '20130115' --check in and check out dates comparison
AND h.location IN ('loc4') --requested location
)
SELECT hotel_name, location, room_type, price, max_adults_allowed, cnt
FROM cte c
WHERE EXISTS (
SELECT 1
FROM dbo.#RoomParams r
WHERE c.cnt >= r.rooms AND c.max_adults_allowed = r.adults
)