ORA-00918: столбец, неоднозначно определенный в SELECT *
Получение 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
Любые предложения, пожалуйста?
Ответы
Ответ 1
Прогноз запроса может иметь только один экземпляр данного имени. Как показано в предложении WHERE, у вас есть несколько таблиц с столбцом с именем ID. Поскольку вы выбираете *
, ваша проекция будет иметь несколько столбцов с именем ID. Или это было бы не для компилятора, который набрасывал ORA-00918.
Решение довольно просто: вам нужно будет расширить проекцию, чтобы явно выбрать именованные столбцы. Затем вы можете либо оставить дубликаты столбцов, сохранив только (скажем) COACHES.ID или использовать псевдонимы столбцов: coaches.id as COACHES_ID
.
Возможно, это поражает вас, как много набрав, но это единственный способ. Если это какой-то комфорт, SELECT *
считается плохой практикой в производственном коде: явно названные столбцы гораздо безопаснее.
Ответ 2
У вас есть несколько столбцов с одинаковыми именами в вашем внутреннем запросе, поэтому ошибка возникает во внешнем запросе. Если вы избавитесь от внешнего запроса, он должен работать, хотя все равно запутаться:
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
Вы также можете увидеть эту ошибку при выборе для объединения, где соответствующие столбцы могут быть пустыми.
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
)
Псевдоним не должен совпадать с соответствующим столбцом, но заголовок столбца в результате управляется первым запросом из членов объединения, поэтому, вероятно, это хорошая практика.