如何将Oracle中两侧带(+)的自连接语法改写为Postgres支持的写法
Oracle转PostgreSQL SQL转换方案
核心语法说明
- Oracle的
(+)是老式外连接语法,PostgreSQL仅支持SQL标准的JOIN类语法,所有外连接逻辑都可以通过LEFT JOIN/RIGHT JOIN/FULL JOIN的ON子句实现 - 你提到的等式两侧均带
(+)且字段都属于T3表的条件T3.u_ffm_sub_id(+) = T3.u_ffm_id(+),本质是外连接阶段的T3表行过滤规则:仅匹配T3表中u_ffm_sub_id = u_ffm_id的行,不满足的话T3侧字段返回NULL,不会过滤MD表的行
等价转换后的PostgreSQL代码
SELECT DISTINCT CASE WHEN MD.u_ffm_id = MD.u_ffm_sub_id THEN MD.patient ELSE T3.patient END INTO lRet FROM UPI.memdate MD LEFT JOIN UPI.memdate T3 ON MD.hmo = T3.HMO AND MD.u_ffm_sub_id = T3.u_ffm_sub_id AND T3.hmo = pHmo AND T3.u_ffm_sub_id = T3.u_ffm_id WHERE md.patient = pPatient;
转换关键点说明
- 把原逗号分隔的隐式连接改成显式
LEFT JOIN,和原Oracle中MD为主表、T3为外连接从表的语义完全一致 - 原T3侧的所有匹配、过滤规则都放到
ON子句中,避免左连接后WHERE过滤把T3为NULL的行删除,保留原逻辑中CASE分支的触发场景 - 原MD侧的过滤条件
md.patient = pPatient保留在WHERE子句中,语义不变
注意:如果原Oracle逻辑中
T3.hmo = pHmo确实不需要保留T3为NULL的行,可将该条件移到WHERE子句中,此时语义等价于内连接。
内容的提问来源于stack exchange,提问作者Shalini
相关产品推荐
相关产品推荐

