我正在使用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;
答案 0 :(得分: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最小化了重复次数,但即便如此也不好 - 并且很可能表现得不如外连接那么好。
当然,在不知道为什么你不能使用外连接的情况下,我不知道是否还有其他限制会使这种方法不可接受......