在SQL Oracle中选择正确的连接

时间:2015-05-28 17:44:35

标签: sql oracle join

鉴于以下表格:

CREATE TABLE TrainInfo
  (
    Trainnumber       INTEGER NOT NULL ,
    nbSits1st         INTEGER NOT NULL ,
    nbAvail1st        INTEGER NOT NULL ,
    nbSits2e          INTEGER NOT NULL ,
    nbAvail2e         INTEGER NOT NULL ,
    Journey_journeyID INTEGER NOT NULL
  ) ;
ALTER TABLE TrainInfo ADD CONSTRAINT TrainInfo_PK PRIMARY KEY ( Trainnumber) ;


CREATE TABLE Journey
  (
    journeyID     INTEGER NOT NULL ,
    departure     VARCHAR2 (45) NOT NULL ,
    arrival       VARCHAR2 (45) NOT NULL ,
    departuretime DATE NOT NULL ,
    arrivaltime   DATE NOT NULL ,
    distance      INTEGER NOT NULL ,
    period        VARCHAR2 (45)
  ) ;
  ALTER TABLE Journey ADD CONSTRAINT Journey_PK PRIMARY KEY ( journeyID) ;


ALTER TABLE TrainInfo ADD CONSTRAINT TrainInfo_FK FOREIGN KEY ( Journey_journeyID)
REFERENCES Journey ( journeyID) ON DELETE CASCADE ;

我想找到" trainnumber,出发,到达,出发时间,到达时间"在这。我试过了:

CREATE VIEW TrainsPossibles AS 
      SELECT trainnumber, departure, arrival, departuretime, arrivaltime 
        FROM TrainInfo 
      NATURAL JOIN Journey 
       ORDER BY departure;

我的问题是,它选择了112(14 * 8)行,而目前我的数据库中只有14个trainInfo和8个旅程。

首先,为什么会创建这么多行?我认为当外键与主键匹配时它会加入,所以最好是14次。

第二:这里的查询或加入是什么? (完全加入FK = PK?)

尝试使用条件:

 SELECT trainnumber, departure, arrival, departuretime, arrivaltime
 FROM TrainInfo JOIN
      Journey
      ON TrainInfo.journey_journeyid = Journey.journeyid AND nbAvail1st != 0 AND nbAvail2e != 0;
 ORDER BY departure;

2 个答案:

答案 0 :(得分:1)

Natural Join 返回记录组合,其中一个表的对应字段与另一个表相对应。这就是你获得如此多记录的原因。

为了得到你需要的东西,你应该进行一次"左连接"而不是"自然加入",用" on"关于TrainInfo.Journey_journeyID =的"的条件 Journey.JourneyID&#34 ;. 左连接返回"左侧"的所有记录。查询和"右侧的所有记录"符合您的"加入条件"如果没有来自"右表" (旅程)存在,你会得到" nulls"在那些专栏中。要仅获取两个表中存在记录的结果,请使用LEFT INNER JOIN。

SELECT trainnumber, departure, arrival, departuretime, arrivaltime 
  FROM TrainInfo 
  LEFT JOIN Journey 
  on TrainInfo.Journey_journeyID = JourneyID
ORDER BY departure

答案 1 :(得分:1)

首先,不要使用OutOfMemoryError。它取决于表中为连接键定义的列。不幸的是,它严格按名称和通过声明的外键引用。如果没有匹配的密钥,那么您将获得一个笛卡尔积。

您的查询是:

NATURAL JOIN

没有列具有相同的名称,因此 SELECT trainnumber, departure, arrival, departuretime, arrivaltime FROM TrainInfo NATURAL JOIN Journey ORDER BY departure; 最终成为笛卡尔积。我想你想要:

JOIN