Oracle ORA-00918 오류 원인과 해결 방법 완벽 가이드

ORA-00918
2026년 06월 17일 | DBMS Error 가이드

이 글에서 다루는 내용

ORA-00918 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.

ORA-00918 column ambiguously defined 는?

ORA-00918 에러는 SQL 쿼리에서 두 개 이상의 테이블에 동일한 이름의 컬럼이 존재할 때, Oracle이 어느 테이블의 컬럼을 참조해야 하는지 명확하게 판단할 수 없을 때 발생합니다. 주로 JOIN 구문을 사용할 때 SELECT 절, WHERE 절, 또는 ORDER BY 절에서 테이블 명시 없이 중복된 컬럼 이름을 사용하는 경우에 나타납니다. 이 에러는 컴파일 단계에서 발생하므로 실행 자체가 불가능하며, 쿼리 작성 시 반드시 수정해야 합니다.


주요 발생 원인

  • JOIN 시 동일한 컬럼명을 테이블 별칭(Alias) 없이 사용

가장 흔한 원인입니다. 두 개 이상의 테이블을 JOIN할 때, 양쪽 테이블 모두에 존재하는 컬럼(예: ID, NAME, STATUS, CREATED_DATE 등)을 SELECT 절에서 테이블 구분 없이 그냥 사용하면 Oracle은 어느 테이블의 컬럼인지 알 수 없어 ORA-00918을 발생시킵니다. 특히 공통 키 컬럼인 DEPT_ID, EMP_ID 같은 FK/PK 컬럼에서 자주 발생합니다.

  • 서브쿼리나 인라인 뷰에서 컬럼명 중복

인라인 뷰(Inline View) 또는 서브쿼리를 사용할 때, 내부 쿼리에서 가져온 컬럼과 외부 테이블의 컬럼 이름이 동일한 경우에도 발생합니다. 인라인 뷰 내부에서 이미 같은 이름의 컬럼이 두 번 선언되거나, 외부 쿼리에서 해당 컬럼을 참조할 때 명확하지 않으면 에러가 발생합니다.

  • USING 절 또는 NATURAL JOIN 사용 후 컬럼 재참조

NATURAL JOIN이나 JOIN ... USING(column) 구문을 사용할 때, USING 절에 명시된 컬럼을 SELECT나 WHERE에서 테이블 별칭을 붙여 참조하면 에러가 발생합니다. 또한 NATURAL JOIN은 동일한 이름의 컬럼을 자동으로 매핑하지만, 이후 해당 컬럼에 테이블 접두어를 붙이면 Oracle이 오히려 모호하다고 판단합니다.


해결 방법

원인 1 해결: 테이블 별칭(Alias)으로 컬럼 명시

문제가 되는 쿼리 예시:

-- ORA-00918 발생: DEPT_ID가 양쪽 테이블에 모두 존재
SELECT DEPT_ID, EMP_NAME, DEPT_NAME
FROM EMPLOYEES e
JOIN DEPARTMENTS d ON e.DEPT_ID = d.DEPT_ID;

해결된 쿼리:

-- 테이블 별칭으로 어느 테이블의 컬럼인지 명확히 지정
SELECT e.DEPT_ID,         -- 또는 d.DEPT_ID 명시적으로 선택
       e.EMP_NAME,
       d.DEPT_NAME
FROM EMPLOYEES e
JOIN DEPARTMENTS d ON e.DEPT_ID = d.DEPT_ID;

SELECT 절에서 모든 컬럼에 테이블 별칭을 붙이는 것이 가장 확실한 해결책입니다.

-- 실무 권장: SELECT 절 전체에 별칭 적용
SELECT e.EMP_ID,
       e.EMP_NAME,
       e.SALARY,
       e.DEPT_ID        AS EMP_DEPT_ID,
       d.DEPT_ID        AS DEPT_DEPT_ID,
       d.DEPT_NAME,
       d.LOCATION_ID
FROM EMPLOYEES e
INNER JOIN DEPARTMENTS d ON e.DEPT_ID = d.DEPT_ID
WHERE e.SALARY > 3000
ORDER BY e.EMP_NAME;

원인 2 해결: 인라인 뷰에서 컬럼 별칭 부여

문제가 되는 쿼리 예시:

-- ORA-00918 발생: 인라인 뷰 내 NAME이 중복
SELECT NAME, TOTAL_SALARY
FROM (
    SELECT e.NAME, d.NAME, SUM(e.SALARY) AS TOTAL_SALARY
    FROM EMPLOYEES e
    JOIN DEPARTMENTS d ON e.DEPT_ID = d.DEPT_ID
    GROUP BY e.NAME, d.NAME
);

해결된 쿼리:

-- 인라인 뷰 내부에서 컬럼 별칭으로 중복 제거
SELECT EMP_NAME, DEPT_NAME, TOTAL_SALARY
FROM (
    SELECT e.NAME       AS EMP_NAME,
           d.NAME       AS DEPT_NAME,
           SUM(e.SALARY) AS TOTAL_SALARY
    FROM EMPLOYEES e
    JOIN DEPARTMENTS d ON e.DEPT_ID = d.DEPT_ID
    GROUP BY e.NAME, d.NAME
);

인라인 뷰 내부에서 반드시 고유한 컬럼 별칭을 부여하면 외부 쿼리에서 안전하게 참조할 수 있습니다.


원인 3 해결: USING 절 컬럼 참조 방식 수정

문제가 되는 쿼리 예시:

-- ORA-00918 발생: USING 절의 컬럼에 테이블 별칭 사용
SELECT e.DEPT_ID, e.EMP_NAME, d.DEPT_NAME
FROM EMPLOYEES e
JOIN DEPARTMENTS d USING (DEPT_ID);
-- USING 절 사용 시 DEPT_ID에 테이블 별칭 e. 또는 d. 붙이면 에러

해결된 쿼리:

-- 방법 1: USING 절의 컬럼은 별칭 없이 단독 사용
SELECT DEPT_ID,           -- 테이블 별칭 없이 사용
       e.EMP_NAME,
       d.DEPT_NAME
FROM EMPLOYEES e
JOIN DEPARTMENTS d USING (DEPT_ID);

-- 방법 2: USING 대신 ON 절로 변경하여 명확하게 처리 (권장)
SELECT e.DEPT_ID,
       e.EMP_NAME,
       d.DEPT_NAME
FROM EMPLOYEES e
JOIN DEPARTMENTS d ON e.DEPT_ID = d.DEPT_ID;

실무에서는 NATURAL JOINUSING 절보다 명시적인 ON 절을 사용하는 것이 유지보수와 가독성 면에서 훨씬 유리합니다.


예방 방법

  • 모든 JOIN 쿼리에서 컬럼에 반드시 테이블 별칭(Prefix) 사용 규칙 적용

팀 내 SQL 코딩 컨벤션으로, JOIN을 포함하는 쿼리에서는 SELECT 절의 모든 컬럼에 테이블 별칭을 붙이는 것을 강제화하는 것이 좋습니다. 이는 ORA-00918뿐만 아니라 향후 테이블 구조 변경 시 발생할 수 있는 예상치 못한 컬럼 충돌도 예방할 수 있습니다. Code Review 단계에서 별칭 미사용 컬럼을 반드시 체크하는 프로세스를 도입하면 실수를 사전에 차단할 수 있습니다.

  • SELECT * 대신 필요한 컬럼만 명시적으로 선택

SELECT 를 사용하면 두 테이블에 동일한 컬럼명이 있을 경우 ORA-00918이 발생할 수 있으며, 불필요한 데이터 전송으로 성능도 저하됩니다. 항상 필요한 컬럼만 명시적으로 나열하고, 각 컬럼에 테이블 별칭을 붙이는 습관을 들이면 에러를 사전에 방지하고 쿼리 성능도 향상시킬 수 있습니다. 특히 대용량 테이블이 포함된 JOIN 쿼리에서 SELECT 는 절대 지양해야 합니다.


관련 에러

  • ORA-00960: ambiguity in column naming in select list — SELECT 목록에서 컬럼 이름 지정이 모호할 때 발생하며, ORA-00918과 유사한 상황에서 나타납니다.
  • ORA-00904: invalid identifier — 존재하지 않는 컬럼 이름을 참조할 때 발생합니다. 잘못된 테이블 별칭을 사용하다가 ORA-00918을 수정하는 과정에서 함께 만날 수 있습니다.
  • ORA-01748: only simple column names allowed here — NATURAL JOIN이나 USING 절에서 테이블 접두어가 붙은 컬럼을 사용할 때 발생하며, ORA-00918과 함께 JOIN 관련 에러로 자주 등장합니다.
  • ORA-00942: table or view does not exist — 잘못된 테이블 별칭이나 테이블 명 오타로 인해 발생하며, JOIN 쿼리 수정 시 연계되어 발생할 수 있습니다.

DBMS 에러 코드 시리즈

주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.

본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.

댓글 남기기