Oracle union 给出错误
Oracle union giving error
我正在尝试在 Oracle 中创建一个视图以显示酒店中所有未预订的可用房间。
如果他们被预订一空,RoomBasket 中会有一条记录。所以我试图 select 在入住和退房日期之间不在 RoomBasket 中的所有房间 (RoomBasket.datein, RoomBasket.dateout)
但是当我使用内部联接和外部 (left/right) 联接时,查询一直返回 0 个结果,我认为这是因为它没有联接到 table 个日期,所以它会有0 个结果。所以现在我正在尝试对房间 table 做一个联合,它有所有房间的记录,因为我认为这会 select 所有房间然后否定那些被预订的房间?
我的语法不正确,我试过这个查询的大量形式:
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 个结果,如果无效,我会收到语法错误。目前错误是:
query block has incorrect number of result columns
您的第一个查询返回的列数与第二个查询不同,因此无法合并它们。明确指定第一个查询的列,而不是使用 SELECT *
.
我让它正常工作是这样的:
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')
)
;
您在 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
谓词的作用是选择左侧 table (Room JOIN RoomType
) 中与右侧 table (table ( RoomBasket
).
我正在尝试在 Oracle 中创建一个视图以显示酒店中所有未预订的可用房间。
如果他们被预订一空,RoomBasket 中会有一条记录。所以我试图 select 在入住和退房日期之间不在 RoomBasket 中的所有房间 (RoomBasket.datein, RoomBasket.dateout)
但是当我使用内部联接和外部 (left/right) 联接时,查询一直返回 0 个结果,我认为这是因为它没有联接到 table 个日期,所以它会有0 个结果。所以现在我正在尝试对房间 table 做一个联合,它有所有房间的记录,因为我认为这会 select 所有房间然后否定那些被预订的房间?
我的语法不正确,我试过这个查询的大量形式:
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 个结果,如果无效,我会收到语法错误。目前错误是:
query block has incorrect number of result columns
您的第一个查询返回的列数与第二个查询不同,因此无法合并它们。明确指定第一个查询的列,而不是使用 SELECT *
.
我让它正常工作是这样的:
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')
)
;
您在 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
谓词的作用是选择左侧 table (Room JOIN RoomType
) 中与右侧 table (table ( RoomBasket
).