我正在尝试在Oracle中创建一个视图,以显示酒店中未预订的所有房间。
如果他们被预订,将会在RoomBasket中有记录。所以我想在入住和结账日期之间选择所有不在RoomBasket的房间(RoomBasket.datein,RoomBasket.dateout)
但是当我使用内部联接和外部(左/右)联接时,查询仍然返回0结果,我认为它是因为它没有连接到日期表,所以它将有0结果。所以现在我正在尝试联盟到Room表,其中有所有房间的记录,因为我认为会选择所有房间,然后否定预订的房间?
我无法正确使用我的语法,并且我使用了大量此类查询:
CREATE VIEW availability AS
(SELECT * FROM RoomBasket rb
WHERE TO_DATE(SYSDATE, 'yyyymmdd')
NOT BETWEEN TO_DATE(rb.datein, 'yyyymmdd') AND TO_DATE(rb.dateout, 'yyyymmdd')
UNION (SELECT r.id room, rt.type type, rt.price price FROM Room r, RoomType rt)
);
但如果它有效,我得到0结果,如果它不起作用,我会得到语法错误。目前错误是:
查询块的结果列数不正确
答案 0 :(得分:3)
您的第一个查询返回的列数与第二个查询不同,因此无法合并。明确指定第一个查询的列,而不是使用SELECT *
。
答案 1 :(得分:3)
您对Room
与RoomType
的加入没有任何谓词,因此您可以获得交叉加入。这不太可能是你想要的。
此外,您的union
似乎正在尝试将不相关的数据添加到房间数据中。您对问题的描述表明您希望使用RoomBasket
数据来过滤其他数据 - 这需要加入或子查询。
这些方面的更多内容可以满足您的需求:
CREATE VIEW availability AS (
SELECT r.id room, rt.type type, rt.price price
FROM
Room r
INNER JOIN RoomType rt
ON rt.id = r.type
LEFT JOIN RoomBasket rb
ON rb.room = r.id
AND TO_DATE(SYSDATE, 'yyyymmdd') BETWEEN TO_DATE(rb.datein, 'yyyymmdd')
AND TO_DATE(rb.dateout, 'yyyymmdd')
WHERE rb.room IS NULL
);
WHERE
谓词具有选择左表(Room JOIN RoomType
)中与右表(RoomBasket
)的任何行不匹配的那些行的效果。
答案 2 :(得分:0)
我这样做是正确的:
CREATE VIEW availability AS
(SELECT
r.id room,
rt.type type,
rt.price price
FROM Room r
INNER JOIN RoomType rt ON r.type = rt.id
INNER JOIN RoomBasket rb ON r.id = rb.room
WHERE TO_DATE(SYSDATE, 'DD-Mon-YYYY')
NOT BETWEEN TO_DATE(rb.datein, 'DD-Mon-YYYY')
AND TO_DATE(rb.dateout, 'DD-Mon-YYYY')
)
;