以下查询会自动从“旧”语法转换为ANSI语法,并出现错误:
select *
from ods_trf_pnb_stuf_lijst_adrsrt2 lst
join ods_stg_pnb_stuf_pers_adr pas
on (pas.soort_adres = lst.soort_adres)
right outer join ods_stg_pnb_stuf_pers_nat nat
on (prs.id = nat.prs_id) <<<prs.id invalid identifier
join ods_stg_pnb_stuf_adr adr
on (adr.id = pas.adr_id)
join ods_stg_pnb_stuf_np prs
on (prs.id = pas.prs_id)
我想这是因为在声明表之前引用了表prs。在查询中移动prs连接可以解决问题:
select *
from ods_trf_pnb_stuf_lijst_adrsrt2 lst
join ods_stg_pnb_stuf_pers_adr pas
on (pas.soort_adres = lst.soort_adres)
join ods_stg_pnb_stuf_np prs <<< this first
on (prs.id = pas.prs_id)
right outer join ods_stg_pnb_stuf_pers_nat nat
on (prs.id = nat.prs_id) <<< now prs.id is known
join ods_stg_pnb_stuf_adr adr
on (adr.id = pas.adr_id)
where lst.persoonssoort = 'PERSOON'
and pas.einddatumrelatie is null
有没有办法编写此查询,以便顺序限制较少,仍然使用ANSI语法?
答案 0 :(得分:3)
除非先前已在联接列表中,否则您无法引用该表。这是正常和预期的行为。为什么这是个问题?
答案 1 :(得分:3)
如果破解的查询是由旧的非ANSI语法的工具生成的,则会生成工具损坏的代码。但是,无论from子句中的表的顺序如何,使用ANSI样式的连接都应该产生相同的结果。那是
select *
from t1
join t2 on t2.id = t1.id
left join t3 on t3.id = t1.id
将为您提供相同的结果(尽管结果集中列的顺序不同)为
select *
from t1
left join t3 on t3.id = t1.id
join t2 on t2.id = t1.id
请注意,from
子句不能以破坏连接条件隐含的依赖关系的方式重新排序。但是,您也可以重新/重构from
子句,以便以不同的方式表达查询,从而产生相同的结果集。例如,上面的查询等同于
select *
from t3
right join t1 on t1.id = t3.id
join t2 on t2.id = t1.id
答案 2 :(得分:0)
正常(“INNER”)JOIN
SELECT ...
FROM a
JOIN b ON (a.x = b.y)
相当于带有两个表的SELECT和一个适当的WHERE子句
SELECT ...
FROM a, b
WHERE a.x = b.y
对于左/右/外连接,您仍然受到“非对称”连接语法的限制。
答案 3 :(得分:0)
我认为最初的SQL代码应该是这样的,
select *
from ods_trf_pnb_stuf_lijst_adrsrt2 lst
, ods_stg_pnb_stuf_pers_adr pas
, ods_stg_pnb_stuf_pers_nat nat
, ods_stg_pnb_stuf_adr adr
, ods_stg_pnb_stuf_np prs
where
pas.soort_adres = lst.soort_adres
and prs.id(+) = nat.prs_id
and adr.id = pas.adr_id
and prs.id = pas.prs_id
and lst.persoonssoort = 'PERSOON'
and pas.einddatumrelatie is null
ods_stg_pnb_stuf_np prs位于from子句的末尾,该子句在Oracle专有连接中有效, 但是当将其转换为ANSI SQL语法时,应该在引用之前先连接表prs。这是人们在将Oracle专有连接转换为ANSI SQL语法时所犯的常见错误。
将Oracle专有连接转换为ANSI SQL语法时还存在一些其他问题:
如果您的同事需要将Oracle专有连接重写为ANSI SQL语法,则本文中列出的demos(both in java and C#)应该会有所帮助。