Oracle union给出了错误

时间:2015-03-31 17:17:53

标签: sql database oracle join union

我正在尝试在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结果,如果它不起作用,我会得到语法错误。目前错误是:

  

查询块的结果列数不正确

3 个答案:

答案 0 :(得分:3)

您的第一个查询返回的列数与第二个查询不同,因此无法合并。明确指定第一个查询的列,而不是使用SELECT *

答案 1 :(得分:3)

您对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谓词具有选择左表(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')
            )
    ;