ORA-00918: столбец неоднозначно определен в SELECT * - PullRequest
27 голосов
/ 04 июня 2011

Получение ORA-00918: столбец двусмысленно определен: запуск этого SQL:

SELECT *
FROM
  (SELECT DISTINCT(coaches.id),
    people.*,
    users.*,
    coaches.*
  FROM "COACHES"
  INNER JOIN people ON people.id = coaches.person_id
  INNER JOIN users ON coaches.person_id = users.person_id
  LEFT OUTER JOIN organizations_users ON organizations_users.user_id = users.id
) WHERE rownum <= 25

Есть предложения, пожалуйста?

Ответы [ 3 ]

46 голосов
/ 04 июня 2011

Проекция запроса может иметь только один экземпляр с заданным именем. Как показывает ваше предложение WHERE, у вас есть несколько таблиц со столбцом с именем ID. Поскольку вы выбираете *, ваша проекция будет иметь несколько столбцов с именем ID. Или это было бы не для компилятора, швыряющего ORA-00918.

Решение довольно простое: вам придется расширить проекцию, чтобы явно выбрать именованные столбцы. Затем вы можете либо пропустить дубликаты столбцов, сохранив только (скажем) COACHES.ID, либо использовать псевдонимы столбцов: coaches.id as COACHES_ID.

Возможно, вам это нравится, когда вы много печатаете, но это единственный способ. Если это утешит, SELECT * считается плохой практикой в ​​производственном коде: столбцы с явно заданными именами намного безопаснее.

9 голосов
/ 04 июня 2011

В вашем внутреннем запросе несколько столбцов с одинаковыми именами, поэтому во внешнем запросе возникает ошибка.Если вы избавитесь от внешнего запроса, он должен запуститься, хотя все еще сбивает с толку:

SELECT DISTINCT
    coaches.id,
    people.*,
    users.*,
    coaches.*
FROM "COACHES"
    INNER JOIN people ON people.id = coaches.person_id
    INNER JOIN users ON coaches.person_id = users.person_id
    LEFT OUTER JOIN organizations_users ON organizations_users.user_id = users.id
WHERE
    rownum <= 25

Было бы намного лучше (для удобочитаемости и производительности) точно указать, какие полявам нужно из каждой таблицы, а не выбирать их в любом случае.Тогда, если вам действительно нужны два поля, называемые одним и тем же из разных таблиц, используйте псевдонимы столбцов, чтобы различать их.

1 голос
/ 03 августа 2017

Вы также можете увидеть эту ошибку при выборе объединения, где соответствующие столбцы могут быть нулевыми.

select * from (select D.dept_no, D.nullable_comment
                  from dept D
       union
               select R.dept_no, NULL
                 from redundant_dept R
)

Это явно сбивает с толку синтаксический анализатор, решение состоит в том, чтобы назначить псевдоним столбца всегда пустому столбцу.

select * from (select D.dept_no, D.comment
                  from dept D
       union
               select R.dept_no, NULL "nullable_comment"
                 from redundant_dept R
)

Псевдоним не должен совпадать сстолбец, но заголовок столбца в результате определяется первым запросом среди членов объединения, так что это, вероятно, хорошая практика.

...