如何连接4个表,条件是数据仅存在于3个表中的2个表中

时间:2010-11-18 23:42:50

标签: sql oracle

我有4个表:t1,t2,t3,t4。我需要显示t1.event_id,t1.event_name,其中t1.event_id仅存在于3个表中的2个(t2,t3,t4)中。我尝试使用join,但我能做的就是返回所有表中存在的event_ids。

这是DDL.sql。

CREATE TABLE t1 
(event_id       NUMBER(15) NOT NULL,
event_name       VARCHAR2(80),
CONSTRAINT pk_event PRIMARY KEY (event_id));

CREATE TABLE t2 
(eid       NUMBER(15) NOT NULL,
equipment      VARCHAR2(100),
CONSTRAINT fk_eid2 FOREIGN KEY (eid)
REFERENCES t1 (event_id) ON DELETE CASCADE);

CREATE TABLE t3
(eid        NUMBER(15) NOT NULL,
security       VARCHAR2(100),
CONSTRAINT fk_eid3 FOREIGN KEY (eid)
REFERENCES t1 (event_id) ON DELETE CASCADE);

CREATE TABLE t4 
(eid       NUMBER(15) NOT NULL,
setup_by      TIMESTAMP,
CONSTRAINT fk_eid4 FOREIGN KEY (eid)
REFERENCES t1 (event_id) ON DELETE CASCADE);

2 个答案:

答案 0 :(得分:1)

不幸的是,我目前没有方便的Oracle(或任何数据库)副本,但我的第一个想法是LEFT OUTER JOIN到每个表,然后通过解码id的存在来过滤掉每张桌子?

SELECT t1.event_id, t1.event_name
  FROM t1
       LEFT OUTER JOIN t2 ON t1.event_id = t2.eid
       LEFT OUTER JOIN t3 ON t1.event_id = t3.eid
       LEFT OUTER JOIN t4 ON t1.event_id = t4.eid
 WHERE (
        DECODE(t2.eid, null, 0, 1) + 
        DECODE(t3.eid, null, 0, 1) + 
        DECODE(t4.eid, null, 0, 1)
       ) >= 2

答案 1 :(得分:0)

如果你需要3个表中的2个,那么这个查询在没有更多逻辑的情况下将无法工作......但是如果你正在寻找缺少3个关系之一的情况,它会。但是,它应该让你开始准备好3个案例中的2个。

select t1.event_id, t1.event_name from t1 left outer join t2 on t1.event_id = t2.eid where t2.eid is null
union
select t1.event_id, t1.event_name from t1 left outer join t3 on t1.event_id = t3.eid where t3.eid is null
union
select t1.event_id, t1.event_name from t1 left outer join t4 on t1.event_id = t4.eid where t4.eid is null

基本上,左外连接将子表的id与null进行比较将有效地获取每个表中缺少的行,然后您可以将结果合并在一起。如果要确保只在一个表中缺少数据,则需要对每个子查询上的其他两个表执行内部联接,以确保它可以正常工作。类似的东西:

select t1.event_id, t1.event_name from t1 left outer join t2 on t1.event_id = t2.eid 
inner join t3 on t1.event_id = t3.eid inner join t4 on t1.event_id = t4.eid 
where t2.eid is null
union
select t1.event_id, t1.event_name from t1 left outer join t3 on t1.event_id = t3.eid 
inner join t2 on t1.event_id = t2.eid inner join t4 on t1.event_id = t4.eid
where t3.eid is null
union
select t1.event_id, t1.event_name from t1 left outer join t4 on t1.event_id = t4.eid 
inner join t3 on t1.event_id = t3.eid inner join t2 on t1.event_id = t2.eid
where t4.eid is null