Подтвердить что ты не робот

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

Любые предложения, пожалуйста?

4b9b3361

Ответ 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
)

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