В этом посту вы узнаете, что значит ошибка «ORA-00918: column ambiguously defined» и как её решить. Ошибка возникает, когда при объединении в двух таблицах присутствуют колонки с одинаковым названием и непонятно, к какой таблице относится колонка.
Для воспроизведения ошибки, создаём две простых таблицы с одинаковыми колонками — цифровой и текстовой. И number_column, и text_column присутствуют в обоих таблицах.
CREATE TABLE test_table1(number_column NUMBER, text_column VARCHAR2(50) )
CREATE TABLE test_table2(number_column NUMBER, text_column VARCHAR2(50) )
Выпоняем запрос SQL с объединением через JOIN, выбираем значения number_column, text_column из таблиц test_table1 и test_table2, в которых number_column из одной равняется number_column из другой, и number_column равняется единице.
SELECT number_column, text_column FROM test_table1 JOIN test_table2 ON number_column = number_column WHERE number_column = 1
Уже прочитав предложение сразу становится понятным, что невозможно определить к какой из двух таблиц относится number_column, а также text_column, что менее очевидно. После выполнения запроса Apex SQL Workshop (или любой другой инструмент для работы с базами данных Oracle) выдаёт такую ошибку:
Скриншот 1: Ошибка ORA-00918: column ambiguously defined
Исправить ситуацию можно двумя методами. В первом просто прописывает название таблицы перед названием колонки.
SELECT test_table1.number_column, test_table1.text_column FROM test_table1 JOIN test_table2 ON test_table1.number_column = test_table2.number_column WHERE test_table1.number_column = 1
Второй метод удобнее. В нём используются алиасы названий таблиц, в нашем примере t1 для test_table1 и t2 для test_table2.
SELECT t1.number_column, t1.text_column FROM test_table1 t1 JOIN test_table2 t2 ON t1.number_column = t2.number_column WHERE t1.number_column = 1
Кстати, в MySQL эта ошибка называется «#1052 — Column ‘number_column’ in field list is ambiguous» и лечится тем же способом. phpMyAdmin выдаёт при такой ошибке следующее сообщение:
Скриншот 2: Ошибка MySQL #1052 — Column in field list is ambiguous
Понравился пост? Поделись в соцсетях и подписывайся на аккаунты в Twitter и Facebook!
SELECT DISTINCT
per_all_people_f.EMPLOYEE_NUMBER
, MAX(per_all_people_f.LAST_UPDATE_DATE)
, per_all_people_f.KNOWN_AS FULL_NAME
, to_char(notified_termination_date, 'DD-MM-YYYY') 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
'لجنة الادارة'
WHEN 'A12' THEN
'قسم الاعلام '
end
END DEPARTMENT
, CASE d_leaving_reason
WHEN 'Retirement' THEN
'التقاعد'
END
LEAVING_REASON1
FROM per_all_people_f
LEFT JOIN per_periods_of_service_v ON per_all_people_f.person_id = per_periods_of_service_v.person_id
LEFT JOIN per_assignments_f ON per_all_people_f.EMPLOYEE_NUMBER = per_assignments_f.ASSIGNMENT_NUMBER
LEFT JOIN hr_all_organization_units_tl ON per_assignments_f.ORGANIZATION_ID = hr_all_organization_units_tl.ORGANIZATION_ID
WHERE notified_termination_date >= TO_DATE(:FROM_DATE,'MM-YYYY') AND notified_termination_date <= TO_DATE(:TO_DATE,'MM-YYYY')
-- AND D_LEAVING_REASON = 'Retirement'
AND CURRENT_EMPLOYEE_FLAG IS NULL AND employee_number IS NOT NULL
GROUP BY EMPLOYEE_NUMBER,d_leaving_reason,LAST_UPDATE_DATE,KNOWN_AS,notified_termination_date
,:FROM_DATE,:TO_DATE,NAME
ORA-00918: column ambiguously defined error occurs when a column name in a join exists in more than one table and is thus referenced ambiguously. The ORA 00918 column ambiguously defined error occurs when attempting to join two or more tables with the same name across columns. This column name is referred as an ambiguous reference. If a column with the same name exists in two or more tables, the column name should be prefixed with the table name in joins. Otherwise, the column is identified ambiguously in the join, and the sql query is unable to determine the column name from the tables. In this scenario, the error message ORA-00918: column ambiguously defined will be shown.
The joins in the sql query combine all of the columns from two or more tables. If a column name is used in two or more tables, the column name is ambiguously recognized in the SQL join. Oracle will give an error ORA-00918: column ambiguously defined, if the column name is used to refer. The reference to the column name should be distinguished in some way. There are several methods for uniquely identifying the column names in the join.
When the ORA-00918 error occur
If two or more tables with the same column name are created and joined in a sql query, the column name may be recognized ambiguously. Because the column name is available in all of the join tables, Oracle could not match with any one table to get the data. The error ORA-00918: column ambiguously defined will be thrown in this scenario.
Problem
create table dept(
deptid number primary key,
deptname varchar2(100)
);
create table employee(
id number primary key,
name varchar2(100),
deptid number, foreign key(deptid) references dept(deptid)
);
select * from dept, employee where deptid=1;
Error
ORA-00918: column ambiguously defined
00918. 00000 - "column ambiguously defined"
*Cause:
*Action:
Error at Line: 16 Column: 36
Root Cause
If more than one table includes the same column name and refers to those columns in a join, the column name will be ambiguous. Oracle will search in the joined tables if you refer to the column name. If the same column name appears in two or more tables, the column name is identified ambiguously. With those tables, the join could not be performed. There is no way to distinguish the columns.
Solution 1
If the same column name appears in multiple tables and is referenced in a join, the column name becomes ambiguous. In sql joins, the column name is identified ambiguously. It is necessary to differentiate the columns in the joins. One method is to prefix the table name when referring it in joins. The table name is used to uniquely identify the column name.
Problem
create table dept(
deptid number primary key,
deptname varchar2(100)
);
create table employee(
id number primary key,
name varchar2(100),
deptid number, foreign key(deptid) references dept(deptid)
);
select * from dept, employee where deptid=1;
ORA-00918: column ambiguously defined
00918. 00000 - "column ambiguously defined"
Solution
select * from dept, employee where dept.deptid=1;
Solution 2
The column name becomes ambiguous if it occurs in many tables and is referenced in a join. The column name is ambiguously recognized in sql joins. In order to separate the columns in the joins, they must be differentiated. If you use the same table in a sql join again, referencing the column by table name will fail. The table alias should be used to refer to the column name in this situation.
Problem
create table employee(
id number primary key,
name varchar2(100),
managerid number, foreign key(managerid) references employee(id)
);
select * from employee, employee where id=managerid;
ORA-00918: column ambiguously defined
00918. 00000 - "column ambiguously defined"
Solution
select * from employee mgr, employee emp where mgr.id=emp.managerid;
Solution 3
When a column name appears in many tables and is referenced in a join, it becomes confusing. In sql joins, the column name is recognized ambiguously. The columns in the joins must be distinct in order to be separated. You may use a select query to change the column names before using them in joins. The select query will provide a list of unique column names to which you may refer. In the example below a select query is used in the joins.
Problem
create table dept(
deptid number primary key,
deptname varchar2(100)
);
create table employee(
id number primary key,
name varchar2(100),
deptid number, foreign key(deptid) references dept(deptid)
);
select * from dept, employee where deptid=1;
ORA-00918: column ambiguously defined
00918. 00000 - "column ambiguously defined"
Solution
select * from dept, (select deptid departmentid from employee) where deptid=1;
Hello. I can’t find my error, even though I am sure it is some kind of syntax error.
Here us my code:
SELECT STUDENT_ID, s.first_name, s.last_name, e.STUDENT_ID, e.section_id, sc.section_id, sc.course_no, sc.instructor_id, co.course_no, co.description, i.instructor_id, i.first_name, i.last_name
FROM INSTRUCTOR i JOIN Section sc
ON i.instructor_id = sc.instructor_id
JOIN Course co
ON sc.course_no = co.course_no
JOIN Section sc
ON sc.section_id = e.section_id
JOIN enrollment e
ON e.student_id = student_id
WHERE upper (s.first_name) = upper (‘Janet’)
And here is my error message:
Error starting at line 1 in command:
SELECT s.student_id, s.first_name, s.last_name, e.student_id, e.section_id, sc.section_id, sc.course_no, sc.instructor_id, co.course_no, co.description, i.instructor_id, i.first_name, i.last_name
FROM INSTRUCTOR i JOIN Section sc
ON i.instructor_id = sc.instructor_id
JOIN Course co
ON sc.course_no = co.course_no
JOIN Section sc
ON sc.section_id = e.section_id
JOIN enrollment e
ON e.student_id = s.student_id
WHERE upper (s.first_name) = upper (‘Janet’)
Error at Command Line:1 Column:0
Error report:
SQL Error: ORA-00918: column ambiguously defined
00918. 00000 — «column ambiguously defined»
*Cause:
*Action:
Learn the cause and how to resolve the ORA-00918 error message in Oracle.
Description
When you encounter an ORA-00918 error, the following error message will appear:
- ORA-00918: column ambiguously defined
Cause
You tried to execute a SQL statement that joined two or more tables, where a column with the same name exists in both tables.
Resolution
The option(s) to resolve this Oracle error are:
Option #1
Prefix the column with the table name and then re-execute the statement.
For example, if you tried to execute the following SQL statement:
SELECT supplier_id, quantity FROM suppliers INNER JOIN orders ON suppliers.supplier_id = orders.supplier_id;
You would receive the following error message:
Since the supplier_id column exists in both the suppliers and orders table, you need to prefix the column with the table name as follows:
SELECT suppliers.supplier_id, quantity FROM suppliers INNER JOIN orders ON suppliers.supplier_id = orders.supplier_id;
Problem
ORA 604 error (ORA-00918) occurred at recursive SQL level
Symptom
PART: API-OM 7.0 SP2 Platform
PRODUCT: Distributed Order
Management
COMPONENT: getOrderList
System throws ORA-604 error while
running some SQL queries.
Cause
Resolving The Problem
There is a bug in Oracle version 9.2.0.0 to 9.2.0.4.
Oracle throws
ORA-604 error while running the query, which has, EXISTS clause in it. Some of
our Yantra query uses this clause. When these queries runs, Oracle throws
‘ambiguous column error’ due to this bug. Example Yantra query is given
below.
The ORA-604 error (ORA-00604: error occurred at recursive SQL
level 1 ORA-00918: column ambiguously defined) can occur for the internal SQL
created for temporary tables if an index join access path has been chosen. This
is most likely to happen in star transformation. This problem can occur on any
platform.
The work around is, to set the initialization parameter
star_transformation_enabled=temp_disable. Or install 9.2.0.5 which brings it’s
own set of problems.
Also refer the Oracle bug ID: 268920.1 in
metalink.
Sample Yantra Query:
====================
SELECT
/*YANTRA*/ YFS_ORDER_HEADER.*
FROM YFS_ORDER_HEADER YFS_ORDER_HEADER
WHERE ( ( YFS_ORDER_HEADER.ENTERPRISE_KEY =’OPNA’ )
AND (
YFS_ORDER_HEADER.ORDER_TYPE = ‘REORDER’ )
AND (
YFS_ORDER_HEADER.BUYER_ORGANIZATION_CODE = ‘222’ )
AND (
YFS_ORDER_HEADER.SELLER_ORGANIZATION_CODE = ‘A3236’ ) )
AND (
ORDER_HEADER_KEY
IN
(SELECT ORDER_HEADER_KEY
FROM YFS_ORDER_LINE
WHERE YFS_ORDER_LINE.ORDER_HEADER_KEY = YFS_ORDER_HEADER.ORDER_HEADER_KEY
AND ( ( YFS_ORDER_LINE.ITEM_ID = ‘RM2122KT’ ) ) ) )
AND
EXISTS
(SELECT ORDER_RELEASE_STATUS_KEY
FROM YFS_ORDER_RELEASE_STATUS
WHERE
STATUS_QUANTITY > ‘0’
AND YFS_ORDER_RELEASE_STATUS.STATUS <> ‘1400’;
AND ( ( YFS_ORDER_RELEASE_STATUS.STATUS >= ‘1100’
AND
YFS_ORDER_RELEASE_STATUS.STATUS <= ‘1100’ ) ) <br>AND
YFS_ORDER_HEADER.ORDER_HEADER_KEY = YFS_ORDER_RELEASE_STATUS.ORDER_HEADER_KEY)
[{«Product»:{«code»:»SS6QYM»,»label»:»Sterling Selling and Fulfillment Suite»},»Business Unit»:{«code»:»BU055″,»label»:»Cognitive Applications»},»Component»:»Not Applicable»,»Platform»:[{«code»:»PF025″,»label»:»Platform Independent»}],»Version»:»All»,»Edition»:»»,»Line of Business»:{«code»:»LOB59″,»label»:»Sustainability Software»}}]
Historical Number
PRI49457
Product Synonym
[<p><b>]Fact[</b><p>];
If you are using the join condition between two tables then both table having the same name column then following error occurred:
SQL> select first_name , department_id from hr.employees emp , hr.departme
nts dept where emp.department_id = dept.department_id;
select first_name , department_id from hr.employees emp , hr.departments d
ept where emp.department_id = dept.department_id
*
ERROR at line 1:
ORA-00918: column ambiguously defined
Solution:
In the we are using two table EMPLOYEES and DEPARTMENTS having one common column DEPARTMENT_ID which caused the error in SQL Statements. We need to use alias name or table reference with the column name. It will fixed the issue.
In following example, when we executed the above query we got the error because in SELECT Query we miss the use of table reference or table alias in front of using that common column. It make difficult for Oracle to understand that column belong to which table.
Highlighted the mistake done in the previous Query.
Use table alias or table reference in front of the common column
SQL> select first_name , emp.department_id from hr.employees emp , hr.departments dept where emp.department_id = dept.department_id;
FIRST_NAME DEPARTMENT_ID
---------- -------------
Ellen 80
Sundar 80