SQL,在oracle中应用两个带条件的左连接

时间:2014-02-14 17:30:37

标签: sql oracle

我有3个表ss(id),aa(id,date)和bb(id,date),每个超过5000000行,我想离开加入这些表来获得这个结果:

  • 如果aa.id == bb.id和aa.date == bb.date,并且表ss中存在aa.id,我想将这些数据连接到同一行(我的例子中的第一行)< / LI>
  • 如果ss.id == aa.id并且aa.id在表bb中不存在或存在但是具有与aa.date不同的“日期”,那么我想只获取相关数据到aa和ss(我的例子中的第三行)
  • 如果ss.id == bb.id并且bb.id在表aa中不存在或者存在但是与bb.date具有不同的“日期”,那么我只想获得相关的数据到bb和ss(我的例子中的第二行)

    ss.id     aa.id         aa.date        bb.id         bb.date
    1             1            2013            1            2013
    1                                          1            2014
    1             1            2012          
    

除了这个操作之外,我还要总结一下这些表中的一些指标(我上面没有提到的其他列)并将它们按ss.dd和Date分组,我做的查询给了我正确的结果,但它在一个不可记录的长时间(超过30分钟)内执行,所以我希望你的帮助解决这个问题,我的查询是这样的

select ss.id,aa.datee,sum(one_of_my_indicators) from ss

left join aa
on ss.id=aa.id

left  join bb
on (
ss.id=bb.id 
and bb.datee=aa.datee
and aa.id is not null
)
 or 
(
ss.id=bb.id 
and aa.id is null
)
group by ss.id,aa.datee;

PS:我的查询中包含所有重要列的索引,例如'ss.id' ,aa和bb的'date'和'id'。 PS:我需要一个条件,从表's'中选择然后做其他其他连接,因为我的查询是一个非常具体的,我必须使用它与另一个工具(Galigeo)。

1 个答案:

答案 0 :(得分:0)

尝试编写查询:

select ss.id, aa.datee,sum(one_of_my_indicators)
from ss left join
     aa
     on ss.id = aa.id left join
     bb
     on ss.id=bb.id and
      ((bb.datee=aa.datee and
         aa.id is not null
        ) or
        aa.id is null
       )
group by ss.id, aa.datee;

Oracle优化器可能不够聪明,无法确定join条件是否相同。

我一直在想,这相当于:

select ss.id, aa.datee,sum(one_of_my_indicators)
from ss left join
     aa
     on ss.id = aa.id left join
     bb
     on ss.id = bb.id and
        bb.date = aa.date
group by ss.id, aa.datee;

此查询是否适用于您正在做的事情?

编辑:

解决此问题的方法是使用两个查询union

select ss.id, aa.datee, sum(one_of_my_indicators)
from ss left join
     aa
     on ss.id = aa.id left join
     bb
     on ss.id=bb.id and
        bb.datee=aa.datee and
        aa.id is not null
group by ss.id, aa.datee;
union all
select ss.id, aa.datee,sum(one_of_my_indicators)
from ss left join
     aa
     on ss.id = aa.id left join
     bb
     on ss.id=bb.id and
        aa.id is null
group by ss.id, aa.datee;

我认为您不需要执行额外的group by,因为aa.datee对于第二个查询应该是NULL并且具有第一个查询的值。