我正在尝试将Informix查询转换为Oracle:
Informix查询如下所示:
SELECT
r.aa, n.bb, nd.cc,u.id, ud.dd, g.attr
FROM
tab1 u, tab2 ud,
OUTER (tab3 a, tab4 n, tab5 nd, tab6 r, OUTER (tab7 g, tab8 atr))
WHERE
r.xx = n.xx AND
n.nas = a.nas AND
a.user = u.user AND
a.ac = g.ac AND
n.nas1 = nd.nas1 AND
u.user1 = ud.user1 AND
atr.sso = g.sso AND
UPPER(atr.name) = 'NAME' AND
u.id = 102
Oracle查询如下所示:
SELECT
r.aa, n.bb, nd.cc,u.id, ud.dd, g.attr
FROM
tab1 u
INNER JOIN tab2 ud ON
u.user1 = ud.user1 AND
u.id = 102
LEFT OUTER JOIN tab3 a ON a.user = u.user
LEFT OUTER JOIN tab4 n ON n.nas = a.nas
LEFT OUTER JOIN tab5 nd ON n.nas1 = nd.nas1
LEFT OUTER JOIN tab6 r ON r.xx = n.xx
我不知道如何加入其他两个表。
任何人都可以帮助我吗?
答案 0 :(得分:8)
我相信查询应该是这样的:
SELECT r.aa, n.bb, nd.cc, u.id, ud.dd, g.attr
FROM tab1 AS u
INNER JOIN tab2 AS v ON u.user1 = v.user1 AND u.id = 102
LEFT OUTER JOIN tab3 AS a ON a.user = u.user
LEFT OUTER JOIN tab4 AS n ON n.nas = a.nas
LEFT OUTER JOIN tab5 AS d ON n.nas1 = d.nas1
LEFT OUTER JOIN tab6 AS r ON r.xx = n.xx
LEFT OUTER JOIN (SELECT g.attr, g.ac
FROM tab7 AS x
JOIN tab8 AS atr ON x.sso = atr.sso
WHERE UPPER(atr.name) = 'NAME'
) AS g ON a.ac = g.ac
我将别名'nd'更改为'd',将'ud'更改为'v',以便所有别名都是单字母。 Informix表示法中的嵌套OUTER(tab7 g, tab8 atr)
本身是内部联接(如我的版本中的子选择),但该结果集与a.ac
外部联接。这就是重写所说的。
我在子查询中使用了WHERE子句;如果您愿意,可以在ON子句中保留WHERE条件。优化程序可能会正确和等效地处理这两种情况。类似地,内部联接中的AND u.id = 102
可以放在WHERE子句中。同样,优化器可能会降低过滤条件以获得更好的性能。
请注意,子查询中的UPPER函数可能需要进行表扫描 - 除非您在UPPER(atr.name)
上有功能索引。
重新审视这一点,查询初始部分的音译不准确。
原始查询包含FROM子句:
FROM tab1 u, tab2 ud, OUTER(tab3 a, tab4 n, tab5 nd, tab6 r, OUTER(tab7 g, tab8 atr))
表tab3
,tab4
,tab5
和tab6
彼此内部联接,结果外部加入tab1
并且tab2
。类似地,tab8
内部连接到tab7
,但结果是外部连接到表3-6的内部连接。我给出的原始答案(基于问题中的大纲答案)将使用旧的Informix表示法表示:
FROM tab1 u, tab2 ud,
OUTER(tab3 a, OUTER(tab4 n, OUTER(tab5 nd, OUTER(tab6 r, OUTER(tab7 g, tab8 atr)))))
因此,将原始查询转录为:
会更准确SELECT r.aa, n.bb, nd.cc, u.id, ud.dd, g.attr
FROM tab1 AS u
JOIN tab2 AS v ON u.user1 = v.user1 AND u.id = 102
LEFT OUTER JOIN
(SELECT *
FROM tab3 AS a ON a.user = u.user
JOIN tab4 AS n ON n.nas = a.nas
JOIN tab5 AS d ON n.nas1 = d.nas1
JOIN tab6 AS r ON r.xx = n.xx
LEFT OUTER JOIN
(SELECT g.attr, g.ac
FROM tab7 AS x
JOIN tab8 AS atr ON x.sso = atr.sso
WHERE UPPER(atr.name) = 'NAME'
) AS g ON a.ac = g.ac
) AS loj
剩下的问题是确保复杂loj
子查询中的列使用了正确的别名。请注意,在没有LEFT,RIGHT或FULL的情况下,JOIN被假定为INNER连接;另外,如果指定LEFT,RIGHT或FULL,则OUTER是可选的。
需要注意的另一个细节:过滤条件下旧式Informix OUTER连接的行为与标准SQL OUTER连接的行为不同。这很少有所作为,但它偶尔可能很重要。总的来说,标准SQL OUTER连接的行为通常更符合您的要求,但如果您运行回归测试并发现答案存在差异,那么解释可能是旧式Informix OUTER连接以不同方式执行来自新式的标准SQL OUTER连接。
答案 1 :(得分:0)
我会尝试添加这些:
LEFT OUTER JOIN tab7 g ON a.ac = g.ac
LEFT OUTER JOIN tab8 atr ON g.sso = atr.sso AND UPPER(atr.name) = 'NAME'