2026년 07월 11일 | DBMS Error 가이드
이 글에서 다루는 내용
42702 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
42702 ambiguous column 란?
PostgreSQL 에러 코드 42702는 ambiguous column, 즉 열 이름이 모호하다는 에러입니다. 이 에러는 쿼리에서 참조하는 컬럼 이름이 두 개 이상의 테이블 또는 서브쿼리에 동일하게 존재할 때 PostgreSQL이 어느 테이블의 컬럼을 사용해야 할지 판단하지 못할 때 발생합니다. 특히 JOIN 구문을 사용하는 복잡한 쿼리에서 자주 발생하며, 테이블 별칭(alias)이나 명시적 테이블 참조 없이 공통 컬럼명을 사용할 경우 빈번하게 나타납니다.
주요 발생 원인
1. JOIN 시 동일한 컬럼명 존재
가장 흔한 원인입니다. 두 개 이상의 테이블을 JOIN할 때, 양쪽 테이블 모두에 동일한 이름의 컬럼이 존재하는 경우 PostgreSQL은 어느 테이블의 컬럼을 참조해야 할지 알 수 없습니다. 예를 들어 orders 테이블과 customers 테이블 모두 id라는 컬럼을 가지고 있을 때, SELECT 절이나 WHERE 절에서 id만 단독으로 사용하면 반드시 이 에러가 발생합니다. 실무에서 가장 많이 마주치는 케이스이며, 특히 ORM이 자동 생성하는 쿼리에서도 종종 발생합니다.
2. 서브쿼리 또는 CTE에서의 컬럼 충돌
서브쿼리나 CTE(Common Table Expression)를 활용하는 복잡한 쿼리에서, 외부 쿼리와 내부 서브쿼리 간에 동일한 컬럼명이 충돌하는 경우에도 발생합니다. 중첩된 쿼리 구조에서는 스코프(scope)가 복잡해지기 때문에, 컬럼이 어느 레벨에서 참조되는지 명확히 지정하지 않으면 에러가 발생합니다. 특히 WITH 절을 여러 개 연결하거나 서브쿼리를 여러 단계로 중첩할 때 더욱 주의가 필요합니다.
3. USING 절 또는 NATURAL JOIN 사용 후 컬럼 참조
NATURAL JOIN 또는 JOIN ... USING (컬럼명) 구문을 사용한 뒤에 해당 컬럼을 SELECT 절에서 테이블 접두사 없이 참조하면 모호성이 발생할 수 있습니다. 일부 상황에서는 USING 절이 양쪽 테이블의 컬럼을 병합한 것처럼 동작하지만, 복잡한 쿼리에서 다른 조건과 함께 사용할 때는 의도하지 않은 모호성이 발생할 수 있습니다. 이 경우에는 명시적인 ON 절을 사용하는 것이 더 안전합니다.
해결 방법
원인 1 해결: 테이블명 또는 별칭으로 컬럼 한정
JOIN 쿼리에서 컬럼 앞에 반드시 테이블명 또는 별칭을 붙여 명확하게 지정합니다.
에러 발생 쿼리:
-- 에러 발생: id가 어느 테이블의 id인지 모호함
SELECT id, orders.amount, customers.name
FROM orders
JOIN customers ON orders.customer_id = customers.id;
해결된 쿼리:
-- 올바른 쿼리: 테이블 별칭으로 컬럼 명확히 지정
SELECT o.id AS order_id, c.id AS customer_id, o.amount, c.name
FROM orders AS o
JOIN customers AS c ON o.customer_id = c.id;
원인 2 해결: CTE 및 서브쿼리에서 컬럼 명확히 지정
CTE나 서브쿼리에서 외부와 내부 모두 테이블 별칭을 사용하여 참조를 명확히 합니다.
에러 발생 쿼리:
-- 에러 발생: created_at이 어느 테이블 것인지 모호
WITH recent_orders AS (
SELECT *
FROM orders
WHERE created_at > NOW() - INTERVAL '7 days'
)
SELECT id, created_at
FROM recent_orders
JOIN customers ON recent_orders.customer_id = customers.id;
해결된 쿼리:
-- 올바른 쿼리: 각 테이블 별칭으로 컬럼 명확히 한정
WITH recent_orders AS (
SELECT
o.id AS order_id,
o.customer_id,
o.amount,
o.created_at AS order_created_at
FROM orders AS o
WHERE o.created_at > NOW() - INTERVAL '7 days'
)
SELECT
ro.order_id,
ro.order_created_at,
c.id AS customer_id,
c.name AS customer_name
FROM recent_orders AS ro
JOIN customers AS c ON ro.customer_id = c.id;
원인 3 해결: NATURAL JOIN 대신 명시적 ON 절 사용
NATURAL JOIN이나 USING 절 대신 명시적인 ON 절을 사용하고, 컬럼에 항상 테이블 별칭을 붙입니다.
권장하지 않는 쿼리:
-- NATURAL JOIN은 모호성과 예기치 않은 동작을 유발할 수 있음
SELECT id, name, amount
FROM customers
NATURAL JOIN orders;
해결된 쿼리:
-- 명시적 ON 절과 별칭으로 안전하게 조인
SELECT
c.id AS customer_id,
c.name AS customer_name,
o.id AS order_id,
o.amount
FROM customers AS c
JOIN orders AS o ON c.id = o.customer_id;
예방 방법
1. 모든 쿼리에서 테이블 별칭과 컬럼 한정자를 습관화하기
쿼리를 작성할 때부터 단일 테이블 쿼리라도 테이블 별칭을 사용하고, 컬럼 앞에 반드시 테이블명 또는 별칭을 붙이는 습관을 들이세요. 특히 팀 전체의 코드 리뷰 기준에 “JOIN이 포함된 쿼리에는 반드시 모든 컬럼에 테이블 별칭을 명시한다”는 규칙을 추가하면 코드 품질과 가독성이 동시에 향상됩니다. SELECT * 사용을 지양하고, 필요한 컬럼만 명시적으로 선택하는 습관 역시 이 에러 예방에 큰 도움이 됩니다.
2. 테이블 설계 시 컬럼명 네이밍 컨벤션 확립하기
데이터베이스 설계 단계에서부터 테이블 간 컬럼명 충돌을 최소화하는 네이밍 컨벤션을 도입하세요. 예를 들어 각 테이블의 기본 키 컬럼은 id 대신 테이블명_id (예: customer_id, order_id) 형식으로 정의하면, JOIN 시 자연스럽게 구별이 됩니다. 또한 created_at, updated_at처럼 공통으로 쓰이는 컬럼명은 쿼리 작성 시 항상 별칭으로 한정하는 팀 규칙을 만들어 두는 것이 좋습니다.
관련 에러
- 42703 undefined_column: 존재하지 않는 컬럼을 참조할 때 발생하는 에러로, 42702와 함께 컬럼 참조 오류의 대표적인 쌍입니다. 42702가 “어떤 테이블의 컬럼인지 모른다”면, 42703은 “그런 컬럼 자체가 없다”는 에러입니다.
- 42P01 undefined_table: 존재하지 않는 테이블을 참조할 때 발생합니다. 잘못된 테이블 별칭 사용이나 오타로 인해 42702와 함께 발생하는 경우가 있습니다.
- 42601 syntax_error: 쿼리 구문 자체가 잘못된 경우 발생하며, 복잡한 JOIN 쿼리를 작성할 때 42702와 혼동되는 경우가 있습니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.