Смешивание «USING» и «ON» в соединении Oracle ANSI - PullRequest
8 голосов
/ 19 января 2009

Я написал выражение Oracle SQL следующим образом:

SELECT
...
FROM mc_current_view a
JOIN account_master am USING (account_no)
JOIN account_master am_loan ON (am.account_no = am_loan.parent_account_no)
JOIN ml_client_account mca USING (account_no)

Когда я пытаюсь запустить его, Oracle выдает ошибку в строке с «ON» self-join, говоря: «ORA-25154: часть столбца предложения USING не может иметь спецификатор».

Если я опускаю квалификатор «am», он говорит: «ORA-00918: столбец определен неоднозначно».

Какой лучший способ решить эту проблему?

Ответы [ 3 ]

13 голосов
/ 26 января 2009

Сообщение об ошибке фактически (удивительно!) Точно говорит вам, в чем проблема. Как только вы используете предложение USING для определенного столбца, вы не можете использовать спецификатор столбца / псевдоним таблицы для имени этого столбца в любой другой части вашего запроса. Единственный способ решить эту проблему - не использовать предложение USING нигде в запросе, поскольку у вас должен быть квалификатор для второго условия соединения:

SELECT
...
FROM mc_current_view a
JOIN account_master am ON (a.account_no = am.account_no)
JOIN account_master am_loan ON (am.account_no = am_loan.parent_account_no)
JOIN ml_client_account mca ON (a.account_no = mca.account_no);
8 голосов
/ 19 января 2009

Я предпочитаю никогда не использовать USING ; всегда используйте ON . Мне бы хотелось, чтобы мой SQL был очень явным, и, по моему мнению, предложение USING кажется на шаг удаленным.

В этом случае возникает ошибка, потому что у вас есть account_no в mc_current_view, account_master и ml_client_account, поэтому фактическое соединение не может быть разрешено. Надеюсь, это поможет.

0 голосов
/ 14 марта 2011

Использование является более чистым (imo), но все же желательно внешне ссылаться на поля объединения, как в примере org или в примере, подобном этому:

select A.field,
       B.field,
       (select count(C.number)
          from tableC C
         where C.join_id = join_id  -- wrong answer w/o prefix, exception with.
        ) avg_number
  from tableA A
  join tableB B using (join_id);

Это дает неправильный ответ, потому что join_id в подзапросе подразумевает C.join_id (соответствует всем записям), а не A или B. Возможно, лучший способ разрешить проблему - это просто разрешить использование явных ссылок с использованием лучшего из обоих миры. Похоже, что есть необходимость из-за подобных случаев.

...