在Oracle中连接表(多个外连接)

div*_*uri 7 sql informix join oracle11g

我正在尝试将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 
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

我不知道如何加入其他两个表.

谁能帮我?

Jon*_*ler 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
Run Code Online (Sandbox Code Playgroud)

我将别名'nd'更改为'd',将'ud'更改为'v',以便所有别名都是单字母.嵌套OUTER(tab7 g, tab8 atr)在Informix表示法中本身就是一个内连接(如我的版本中的子选择),但该结果集是外连接的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))
Run Code Online (Sandbox Code Playgroud)

tab3,tab4,tab5tab6是内彼此接合,其结果是外连结到tab1tab2.类似地,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)))))
Run Code Online (Sandbox Code Playgroud)

因此,将原始查询转录为更准确:

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
Run Code Online (Sandbox Code Playgroud)

剩下的问题是确保正在使用复杂loj子查询中的列的正确别名.请注意,在没有LEFT,RIGHT或FULL的情况下,JOIN被假定为INNER连接; 另外,如果指定LEFT,RIGHT或FULL,则OUTER是可选的.

另一个需要注意的细节:过滤条件下旧式Informix OUTER连接的行为与标准SQL OUTER连接的行为不同.这很少有所作为,但它偶尔可能很重要.总的来说,标准SQL OUTER连接的行为通常更符合您的要求,但如果您运行回归测试并发现答案存在差异,那么解释可能是旧式Informix OUTER连接以不同方式执行来自新式的标准SQL OUTER连接.


Los*_*ama 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'
Run Code Online (Sandbox Code Playgroud)