-1

我正在使用 Oracle 数据库,并且我有一个查询,我必须在其中执行 7 个不同表的连接。现在,我的问题是,我需要获取满足连接要求的行(显然),但即使它们与最后一个连接的条件不匹配,我也需要从前 6 个表中获取行。我不能做左外连接,那么我有什么选择?

代码看起来像这样:

    with
tmp as (select col1, col2, col3, col4, row_number() over (partition by col1 order by col2 desc) rn
            from
            (select /*+ MATERIALIZE */
              col1, col2, col3, col4
             from
              table1
             where 
              col3 in ('A','R','F') and
              somedate >= sysdate-720 and
              col5 is null
              and col1<> '0000000000'))
select /*+ use_hash(a,b,c,d,e,f,g,h) */
b.col5,
a.col1, 
 d.col6, 
 e.col7, 
 c.col8 , 
 (CASE when f.col9= 'B' then 'Foo' else 'Bar' END) as "col9", 
 a.col2, 
 a.col3,
 h.col10
from tmp a
     join table2 b on
      a.col1= b.col1 and
      a.col4=b.col4 and
      b.col11='P' and
      (b.otherDate>= sysdate OR b.otherDate is null)  and
      b.col5 is null 
     join table3 c on
      b.col12 = c.col12 and
      (c.otherDate is null or b.otherDate >= sysdate) and
      c.col5 is null 
     join table4 d on
      a.col1= d.col1 and
      d.col13 in ('R','A','F') and
      d.col5 is null 
     join table5 e on
      e.col1=b.col1 and
      e.col14=d.col14 and
      d.col6=e.col6 and
      d.col15 = e.col15 and
      e.col5 is null       
    join table6 f on
      f.col4= a.col4 and 
      f.col5 is null
    join table7 g on 
      g.col16=  case when f.col15 is null then null else f.col15 end
      and g.col5is null
      and (g.otherDate is null or g.otherDate >= sysdate)
    join table8 h on 
      h.col17= g.col17
      and (h.otherDate >= sysdate or h.otherDate is null)
      and h.col5 is null
      and a.rn=1;
4

1 回答 1

2

我不会尝试使用您的实际查询,但原则上您可以更改:

select tab1.col1, tab2.col2, tab3.col3
from tab1
join tab2 on tab2.fk = tab1.pk
join tab3 on tab3.fk = tab2.pk

进入:

select tab1.col1, tab2.col2, tab3.col3
from tab1
join tab2 on tab2.fk = tab1.pk
left join tab3 on tab3.fk = tab2.pk

您可以将其替换为(在您的不允许加入的世界中):

with tmp as (
    select tab1.col1, tab2.col2, tab3.pk
    from tab1
    join tab2 on tab2.fk = tab1.pk
)
select tmp.col1, tmp.col2, tab3.col3
from tmp
join tab3 on tab3.fk = tmp.pk
union all
select tmp.col1, tmp.col2, null as col3
from tmp
where not exists (
    select null from tab3
    where tab3.fk = tmp.pk
)

这很丑 - 我已经用 CTE 最小化了重复,但即使这样也不好 - 并且可能不会像外部连接那样执行。

当然,在不知道为什么不能使用外连接的情况下,我不知道是否还有其他限制会使这种方法也无法接受......

于 2013-05-17T12:08:23.850 回答