使用旧式联接进行左联接

时间:2019-01-07 09:30:07

标签: sql postgresql database-migration outer-join

因此,我目前正在将OracleSQL转录为新的PostgreSQL数据库。当我将Oracle的(+)的联接转换为LEFT OUTER JOIN时,这很好。

与旧式联接结合使用时除外。以这个OracleSQL为例:

SELECT
    *
FROM
    table1,
    table2 alias1,
    table2 alias2,
    table2 alias3,
    table3,
    table4,
    table5,
    table6 table6alias
WHERE
    table1.id_table3 = alias1.id_table3
    AND table1.id_table4 = alias2.id_table4
    AND table1.id_table3 = table3.id_table3
    AND table1.id_table4 = table4.id_table4
    AND table1.id_table5 = table5.id_table5
    AND table1.table1_id_table3_sender = alias3.id_table3 (+)
    AND alias1.id_svw_uebertragungsweg = table6alias.id_svw
    AND table1.id_table3 != 0
    AND ( table1.id_usr = 0
          OR table1.id_usr IS NULL )

它在Oracle的SQL Developer上运行良好。所以我尝试像这样转录它:

SELECT
    *
FROM
    table1,
    table2 alias1,
    table2 alias2,
    table3,
    table4,
    table5,
    table6 table6alias
LEFT OUTER JOIN table2 alias3
ON table1.table1_id_table3_sender = alias3.id_table3
WHERE
    table1.id_table3 = alias1.id_table3
    AND table1.id_table4 = alias2.id_table4
    AND table1.id_table3 = table3.id_table3
    AND table1.id_table4 = table4.id_table4
    AND table1.id_table5 = table5.id_table5
    AND alias1.id_svw_uebertragungsweg = table6alias.id_svw
    AND table1.id_table3 != 0
    AND ( table1.id_usr = 0
          OR table1.id_usr IS NULL )

给我这个错误:

  

ORA-00904:“ table1”。“ table1_id_table3_sender”:无效的标识符   00904. 00000-“%s:无效的标识符”   *原因:
  *行动:   在线错误:12行:8

我只做过 JOIN,然后它可以完美地工作。当仅添加一个其他的JOIN时,它给了我这个错误,即找不到该行(无效的标识符)。

我已经在互联网上读到LEFT JOIN的内容只比FROM语句的第一个表多。但是在这种情况下(我认为)就足够了-仅添加另一个表也会导致错误。

那么解决这种PostgreSQL翻译的方法是什么?我是否必须将所有旧样式的JOIN重写为较新的样式(这很繁琐,因为其中有大量的SELECT),还是我只是不注意?

3 个答案:

答案 0 :(得分:3)

不要混用显式和隐式JOIN。实际上,只是不要使用隐式JOIN。

这是您想要的查询:

SELECT
    *
FROM
    table1
    INNER JOIN table2 alias1 ON table1.id_table3 = alias1.id_table3 
    INNER JOIN table2 alias2 ON table1.id_table4 = alias2.id_table4
    INNER JOIN table3 ON table1.id_table3 = table3.id_table3
    INNER JOIN table4 ON table1.id_table4 = table4.id_table4
    INNER JOIN table5 ON table1.id_table5 = table5.id_table5
    INNER JOIN table6 table6alias ON alias1.id_svw_uebertragungsweg = table6alias.id_svw
    LEFT JOIN table2 alias3 ON table1.table1_id_table3_sender = alias3.id_table3
WHERE
    table1.id_table3 != 0
    AND ( table1.id_usr = 0 OR table1.id_usr IS NULL )

答案 1 :(得分:2)

问题是(不确定是否是标准的,但大多数数据库引擎似乎都遵循它)显式连接在隐式连接之前被处理。在进行连接时,范围内仅有的表/别名为table6aliasalias3。但是您正在尝试在table1子句中引用ON进行连接。

您怀疑,解决方案是在整个过程中使用显式联接,这也使您可以更好地控制联接的发生顺序。

(或者快速解决方案是将LEFT JOIN之后的alias3放到table1

答案 2 :(得分:0)

您执行的加入错误,应该是这样的:

SELECT
 *
FROM
 table1 left outer join table2 alias3 on table1.table1_id_table3_sender = 
 alias3.id_table3,
 table2 alias1,
 table2 alias2,
 table3,
 table4,
 table5,
 table6 table6alias
WHERE
table1.id_table3 = alias1.id_table3
AND table1.id_table4 = alias2.id_table4
AND table1.id_table3 = table3.id_table3
AND table1.id_table4 = table4.id_table4
AND table1.id_table5 = table5.id_table5
AND alias1.id_svw_uebertragungsweg = table6alias.id_svw
AND table1.id_table3 != 0
AND ( table1.id_usr = 0
      OR table1.id_usr IS NULL )