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')
            )
    ;

您在 RoomRoomType 的联接上没有谓词,因此您得到了交叉联接。这不太可能是你想要的。

此外,您的 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).