限制FULL OUTER JOIN中使用的表中的值

时间:2014-04-15 20:00:33

标签: sql oracle join

这涉及Oracle SQL。

考虑以下3个表:

TRIP_SEGMENT:

CREATE TABLE TRIP_SEGMENT(
   SEG_ID NUMBER(6) NOT NULL,
   DIRECTION VARCHAR(8) NOT NULL,
   DEPARTURE_LOCATION VARCHAR(50) NOT NULL,
   DESTINATION VARCHAR(50) NOT NULL,
   SEGMENT_PRICE NUMBER(5,2) NULL,
   TRIP_ID NUMBER(6) NOT NULL,
   CONSTRAINT chk_SEG_DIRECTION CHECK (DIRECTION IN ('Outbound','Inbound')),
   CONSTRAINT pk_SEGMENT PRIMARY KEY (SEG_ID),
   CONSTRAINT fk_TRIP_ID FOREIGN KEY (TRIP_ID) REFERENCES TRIP(TRIP_ID)
);

交通:

CREATE TABLE TRANSPORTATION(
   TRANSP_BOOK_ID NUMBER(6) NOT NULL,
   TRANSP_PRICE NUMBER(5,2) NULL,
   DEPARTURE_DATE DATE NULL,
   ARRIVAL_DATE DATE NULL,
   EXT_BOOK_ID NUMBER(6) NULL,
   SEG_ID NUMBER(6) NOT NULL,
   SERV_TYPE_ID NUMBER(3) NOT NULL,
   PARTNER_ID NUMBER(3) NULL,
   CONSTRAINT pk_TRANSP_BOOK_ID PRIMARY KEY (TRANSP_BOOK_ID),
   CONSTRAINT fk_TRANSP_SEG_ID FOREIGN KEY (SEG_ID) REFERENCES TRIP_SEGMENT(SEG_ID),
   CONSTRAINT fk_TRANSP_SERV_ID FOREIGN KEY (SERV_TYPE_ID) REFERENCES SERVICE_TYPE(SERV_TYPE_ID),
   CONSTRAINT fk_TRANSP_PARTNER_ID FOREIGN KEY (PARTNER_ID) REFERENCES PARTNER(PARTNER_ID)
);

PARTNER:

CREATE TABLE PARTNER(
   PARTNER_ID NUMBER(3) NOT NULL,
   PARTNER_NAME VARCHAR(50) NOT NULL,
   CONTACT_FNAME VARCHAR(20) NOT NULL,
   CONTACT_LNAME VARCHAR(20) NOT NULL,
   ADDRESS VARCHAR(100) NULL,
   PHONE_NO NUMBER(20) NOT NULL,
   EMAIL VARCHAR(50) NULL,
   SERV_TYPE_ID NUMBER(3) NOT NULL,
   CONSTRAINT pk_PARTNER_ID PRIMARY KEY (PARTNER_ID),
   CONSTRAINT fk_PART_SERV_ID FOREIGN KEY (SERV_TYPE_ID) REFERENCES SERVICE_TYPE(SERV_TYPE_ID)
);

我想像这样创建一个FULL OUTER JOIN

SELECT TS.SEG_ID, TS.DEPARTURE_LOCATION, TS.DESTINATION, P.PARTNER_NAME
   FROM TRIP_SEGMENT TS
   FULL OUTER JOIN TRANSPORTATION T
    ON TS.SEG_ID = T.SEG_ID
   FULL OUTER JOIN PARTNER P
    ON T.PARTNER_ID = P.PARTNER_ID;

...但仅限于PARTNER.PARTNER_ID < 6。如果我只是在JOIN的末尾添加一个WHERE子句,这会将所有值限制为与PARTNER.PARTNER_ID < 6有关联的值,因此无法实现FULL OUTER JOIN的目的。

到目前为止,我已经提出了这个解决方案:

首先,创建一个仅包含PARTNER.PARTNER_ID < 6的表:

CREATE TABLE TRANSPORTATION_PARTNER AS SELECT * FROM PARTNER WHERE PARTNER_ID < 6;

然后,在FULL OUTER JOIN中使用该表:

SELECT TS.SEG_ID, TS.DEPARTURE_LOCATION, TS.DESTINATION, TP.PARTNER_NAME
   FROM TRIP_SEGMENT TS
   FULL OUTER JOIN TRANSPORTATION T
    ON TS.SEG_ID = T.SEG_ID
   FULL OUTER JOIN TRANSPORTATION_PARTNER TP
    ON T.PARTNER_ID = TP.PARTNER_ID;

这很好用,它演示了我想要实现的目标,但是我想知道是否有一种方法可以在一个查询中使用子查询。

谢谢!

2 个答案:

答案 0 :(得分:1)

是的,只需执行以下操作:

SELECT TS.SEG_ID, TS.DEPARTURE_LOCATION, TS.DESTINATION, P.PARTNER_NAME
FROM TRIP_SEGMENT TS
FULL OUTER JOIN TRANSPORTATION T
   ON TS.SEG_ID = T.SEG_ID
FULL OUTER JOIN (SELECT * 
                 FROM PARTNER 
                 WHERE PARTNER.PARTNER_ID < 6) P
   ON T.PARTNER_ID = P.PARTNER_ID;

答案 1 :(得分:0)

您对要选择的行设置了限制,因此您可以使用LEFT JOIN代替FULL OUTER JOIN。尝试像

这样的东西
SELECT TS.SEG_ID, TS.DEPARTURE_LOCATION, TS.DESTINATION, P.PARTNER_NAME
FROM TRIP_SEGMENT TS
    FULL OUTER JOIN TRANSPORTATION T
        ON TS.SEG_ID = T.SEG_ID
    LEFT OUTER JOIN PARTNER P
        ON T.PARTNER_ID = P.PARTNER_ID AND P.Partner_ID = 6;