- Error code
- ORA-00918
- Product
- Oracle Database
- Versions
- Oracle Database 19c, 21c, 23ai and 26ai (wording differs: see below)
- Category
- Objects, Names & Identifiers
- Last reviewed
- 24 October 2026
On this page
What it means
ORA-00918 means a query joins two or more tables that both have a column with the same name, and the statement refers to that column without saying which table it comes from.
In a join, any column name that occurs in more than one of the tables must be prefixed with its table name or table alias. Oracle's reference uses the classic case: if EMP and DEPT are joined and both have DEPTNO, every reference must be EMP.DEPTNO or DEPT.DEPTNO (or an alias such as E.DEPTNO). Without the prefix Oracle cannot decide which column you mean and refuses to guess.
The rule applies to every clause of the query: the SELECT list, WHERE, GROUP BY, ORDER BY and join conditions. Current releases name the column and two of the tables in the message, which points straight at the fix; 19c and 21c print only "column ambiguously defined", so you have to find the unqualified column yourself. Shared column names such as ID, NAME, STATUS, CREATED_AT and foreign key columns are the usual suspects.
Common causes
- A join selects a column that exists in both tables (for example CUSTOMER_ID in ORDERS and CUSTOMERS) without a table alias.
- WHERE, GROUP BY or ORDER BY uses an unqualified column that is shared by joined tables, even though the SELECT list is qualified.
- A new column is added to one table with a name another joined table already uses, so a query that used to work starts failing.
- A query joins the same table twice (a self-join) and refers to a column without the alias of the copy it means.
Diagnose it
Read-only These queries only read the data dictionary (USER_, ALL_ and DBA_ views) and dynamic performance views (V$). They do not change data, privileges or settings, so they are safe to run first. DBA_ and V$ views need the matching privileges.
Which joined tables share the column?
On 19c the message does not name the column. List the columns that appear in more than one of the tables in your FROM clause.
SELECT column_name, LISTAGG(table_name, ', ') WITHIN GROUP (ORDER BY table_name) AS in_tables
FROM all_tab_columns
WHERE owner = 'SHOP'
AND table_name IN ('ORDERS', 'CUSTOMERS')
GROUP BY column_name
HAVING COUNT(*) > 1
ORDER BY column_name; Every column name the tables have in common. Each of them must be qualified wherever the query uses it.
Read the statement clause by clause
Go through the SELECT list, the join conditions, WHERE, GROUP BY, HAVING and ORDER BY, and look for any of the shared names without an alias in front. In SQL*Plus and SQLcl the asterisk under the statement marks the position Oracle stopped at.
How to fix it
Each fix is labelled with what it changes. Try read-only checks and the least invasive fix first, and test changes outside production.
Give every table an alias and qualify every column
Read-onlyThis is Oracle's documented fix, and qualifying all columns (not only the ambiguous one) also protects the query when a table later gains a column with the same name.
SELECT o.order_id, o.customer_id, c.name
FROM shop.orders o
JOIN shop.customers c ON c.customer_id = o.customer_id
WHERE o.status = 'OPEN'
ORDER BY o.order_id;
Join with USING when the shared column is the join key
Read-onlyWith JOIN ... USING (customer_id) the join column appears once in the result and is referenced without any prefix. Do not qualify it with a table alias anywhere in the query.
SELECT order_id, customer_id, name
FROM shop.orders
JOIN shop.customers USING (customer_id);
Give same-named columns distinct aliases in the SELECT list
Read-onlyWhen both tables' columns are needed, give them distinct aliases, so outer queries and views can refer to each one unambiguously.
SELECT o.status AS order_status, c.status AS customer_status
FROM shop.orders o
JOIN shop.customers c ON c.customer_id = o.customer_id;
Examples
Selecting the join column without an alias
Not reproduced here: no Oracle Database is installed for this site. The result follows the current message format in Oracle's error reference, which names the column and two of the joined tables; the names are filled in from this example, and the exact form (table name or alias, quoting) is illustrative. Oracle Database 19c prints "ORA-00918: column ambiguously defined".
SELECT order_id, customer_id, name
FROM orders o
JOIN customers c ON c.customer_id = o.customer_id;
ORA-00918: CUSTOMER_ID: column ambiguously specified - appears in ORDERS and CUSTOMERS
An unqualified column in WHERE
Not reproduced here: no Oracle Database is installed for this site. The result is shown in the 19c form from Oracle's error reference; current releases add the column and table names. The SELECT list is qualified, but the WHERE clause is not, which is enough to raise the error.
-- both tables have a STATUS column
SELECT o.order_id, c.name
FROM orders o
JOIN customers c ON c.customer_id = o.customer_id
WHERE status = 'OPEN';
ORA-00918: column ambiguously defined
How to prevent it
Make it a habit to alias every table in a join and prefix every column, in every clause. Many teams enforce this in code review because it keeps queries working when someone adds a column with a common name such as STATUS or UPDATED_AT to one of the tables.
Name foreign key columns after the key they reference (customer_id in both tables) so joins read naturally, and use USING or qualified names for them consistently.
Common questions
How do I fix ORA-00918 column ambiguously defined?
Find the column that exists in more than one joined table and prefix it with a table alias everywhere it is used: the SELECT list, join conditions, WHERE, GROUP BY and ORDER BY.
Why did a query that worked yesterday start raising ORA-00918?
A column with the same name was probably added to one of the joined tables, so an unqualified reference that used to be unique is now ambiguous. Qualifying every column prevents this.
Why does the newer message say "column ambiguously specified"?
Oracle reworded the message in current releases to name the column and the tables it appears in. 19c and 21c print "column ambiguously defined". The cause and the fix are the same.
Learn more on CodeWithSQL
Official documentation
- ORA-00918 (Oracle Database Error Messages)
- Joins (Oracle SQL Language Reference 19c)
- SELECT (Oracle SQL Language Reference 19c)
Last technically reviewed 24 October 2026; examples and diagnostics run on Oracle Database Error Messages reference (26ai, 21c and 19c); not run locally. Messages and explanations follow Oracle's Database Error Messages reference; no Oracle Database was available, so the examples were not run locally.