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
Любые предложения, пожалуйста?
4 ответа
Проекция запроса может иметь только один экземпляр с заданным именем. Как показывает ваше предложение WHERE, у вас есть несколько таблиц со столбцом с именем ID. Потому что вы выбираете *
Ваша проекция будет иметь несколько столбцов с именем ID. Или это было бы не для компилятора, швыряющего ORA-00918.
Решение довольно простое: вам придется расширить проекцию, чтобы явно выбрать именованные столбцы. Затем вы можете либо пропустить дубликаты столбцов, сохранив только (скажем) COACHES.ID, либо использовать псевдонимы столбцов: coaches.id as COACHES_ID
,
Возможно, это впечатляет, как много печатать, но это единственный способ. Если это какой-то комфорт, SELECT *
считается плохой практикой в производственном коде: явно именованные столбцы намного безопаснее.
У вас есть несколько столбцов с одинаковыми именами во внутреннем запросе, поэтому ошибка возникает во внешнем запросе. Если вы избавитесь от внешнего запроса, он должен запуститься, хотя все еще сбивает с толку:
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
Было бы гораздо лучше (с точки зрения читабельности и производительности) точно указать, какие поля вам нужны в каждой из таблиц, а не выбирать их все в любом случае. Тогда, если вам действительно нужны два поля, называемые одним и тем же из разных таблиц, используйте псевдонимы столбцов, чтобы различать их.
Вы также можете увидеть эту ошибку при выборе объединения, где соответствующие столбцы могут быть нулевыми.
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
)
Псевдоним не обязательно должен совпадать с соответствующим столбцом, но заголовок столбца в результате определяется первым запросом среди членов объединения, так что это, вероятно, хорошая практика.
ВЫБРАТЬ DISTINCT на_все_люди_f.EMPLOYEE_NUMBER
, МАКС (за_все_люди_f.LAST_UPDATE_DATE)
,per_all_people_f.KNOWN_AS FULL_NAME
,to_char(дата_предложения_уведомления, 'ДД-ММ-ГГГГ') AS termination_date
,:FROM_DATE DATE1
,: TO_DATE DATE2
-, D_LEAVING_REASON AS D_LEAVING_REASON
, CASE substr (substr (hr_all_organization_units_tl.NAME,
instr (hr_all_organization_units_tl.NAME, '.') + 1), 1, 1)
WHEN 'B' THEN
'إدارة الاتصالات وتقنية المعلومات'
WHEN 'C' THEN
'إدارة المشاريع'
WHEN 'D' THEN
'الإدارة القانونية'
WHEN 'E' THEN
'إدارة الصحه والسلامة والبيئه'
WHEN 'F' THEN
'إدارة هندسة المكامن والانتاج'
WHEN 'G' THEN
'إدارة الهندسة'
WHEN 'H' THEN
'إدارة العمليات'
WHEN 'J' THEN
'إدارة الحفر وصيانة الآبار'
WHEN 'K' THEN
'إدارة المواد'
WHEN 'L' THEN
'إدارة النقل والخدمات'
WHEN 'M' THEN
'إدارة الاستكشاف'
WHEN 'N' THEN
'إدارة فرع بنغازي'
WHEN 'P' THEN
'إدارة التخطيط'
WHEN 'R' THEN
'إدارة المالية'
WHEN 'T' THEN
'إدارة المراجعه'
WHEN 'W' THEN
'إدارة التدريب والتطوير'
WHEN 'Y' THEN
'إدارة شؤون الموظفين'
else case substr(substr(hr_all_organization_units_tl.NAME, instr(hr_all_organization_units_tl.NAME, '.') + 1), 1, 3)
WHEN 'A11' THEN
'لجنة المناقصات'
WHEN 'A10' THEN
'لجنة الادارة'
КОГДА 'A12' ТОГДА 'سم الاعلام' заканчиваются КОНЕЧНЫМ ОТДЕЛОМ, СЛУЧАЙ d_leaving_reason
WHEN 'Retirement' THEN
'التقاعد'
END
LEAVING_REASON1
FROM per_all_people_f
левое соединение per_periods_of_service_v на per_all_people_f.person_id = per_periods_of_service_v.person_id левое соединение per_assignments_f на per_all_people_f.EMPLOYEE_NUMBER = per_assignments_f.ASSIGNMENT_NUMBER слева присоединиться hr_all_organization_units_tl на per_assignments_f.ORGANIZATION_ID = hr_all_organization_units_tl.ORGANIZATION_ID где notified_termination_date> = TO_DATE (:FROM_DATE, 'MM-YYYY') И notified_termination_date <= TO_DATE (: TO_DATE, 'MM-YYYY') --AND D_LEAVING_REASON = 'Retirement'AND CURRENT_EMPLOYEE_FLAG имеет значение NULL, а значение employee_number не равно NULL GROUP BY EMPLOYEE_NUMBER,d_leaving_reason, LOMAS_UPDATE_DATE, FROM_TERNATION:FROM_TERNATION, FROM_TERNATION