Выполнение левого соединения со старыми стилями - PullRequest
0 голосов
/ 07 января 2019

Итак, в настоящее время я транскрибирую OracleSQL в новую базу данных PostgreSQL. В то время как я перевожу соединения (+) Oracle в LEFT OUTER JOIN s, это работает очень хорошо.

За исключением случаев, когда сочетается со старым стилем. Возьмите этот 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 возникает ошибка: не удается найти строку (неверный идентификатор).

Я уже читал в интернете, что ЛЕВЫЕ СОЕДИНЕНИЯ не краснее, чем первая таблица оператора FROM. Но в этом случае этого будет достаточно (на мой взгляд) - просто добавление еще одной таблицы приводит к ошибке.

Так каков мой подход к решению этого перевода в PostgreSQL? Должен ли я переписать ВСЕ из старых стилей JOIN в более новые (что было бы очень утомительно, так как есть множество этих SELECT) или есть что-то, на что я просто не замечаю?

Ответы [ 3 ]

0 голосов
/ 07 января 2019

Проблема заключается в том (не уверен, что это стандарт, но большинство механизмов баз данных, похоже, следуют ему), явные объединения обрабатываются до неявных объединений. В момент, когда вы выполняете объединение, единственные таблицы / псевдонимы, которые находятся в области видимости, это table6alias и alias3. Но вы пытаетесь сослаться на table1 в предложении ON для объединения.

Как вы и подозревали, решение заключается в использовании явных объединений, что также дает вам больше контроля над порядком, в котором происходят объединения.

(Или быстрое решение было бы поставить LEFT JOIN в alias3 сразу после table1)

0 голосов
/ 07 января 2019

Вы делаете неправильное объединение, оно должно быть таким:

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 )
0 голосов
/ 07 января 2019

Не смешивайте явные и неявные СОЕДИНЕНИЯ. На самом деле, просто не используйте неявные соединения.

Вот запрос, который вы хотите:

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 )
...