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

ORA-01791
2026년 08월 01일 | DBMS Error 가이드

이 글에서 다루는 내용

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

ORA-01791 not a SELECTed expression 는?

ORA-01791 에러는 ORDER BY 절에서 참조하는 컬럼 또는 표현식이 SELECT 절에 포함되어 있지 않을 때 발생하는 오류입니다. 특히 DISTINCT, UNION, INTERSECT, MINUS 등의 집합 연산자를 사용하는 쿼리에서 자주 나타납니다. Oracle은 이러한 연산 시 결과 집합의 중복을 제거하거나 집합을 합산하는 과정에서 ORDER BY에 명시된 컬럼이 SELECT 목록에 없으면 정렬 기준을 특정할 수 없기 때문에 이 에러를 발생시킵니다.


주요 발생 원인

1. DISTINCT와 함께 SELECT되지 않은 컬럼으로 ORDER BY 사용

SELECT DISTINCT를 사용할 경우 Oracle은 중복 제거를 위해 선택된 컬럼만 인식합니다. ORDER BY 절에 SELECT 목록에 없는 컬럼을 지정하면 Oracle이 해당 컬럼의 값을 결과 집합에서 확인할 수 없어 에러가 발생합니다. 이는 가장 흔하게 발생하는 원인으로, 초보자뿐 아니라 숙련된 개발자도 자주 실수하는 패턴입니다.

2. UNION / UNION ALL / INTERSECT / MINUS 집합 연산자 사용 시 ORDER BY 컬럼 불일치

집합 연산자를 사용하는 복합 쿼리에서는 최종 ORDER BY 절이 첫 번째 SELECT 절의 컬럼 목록을 기준으로 동작합니다. 두 번째 이후의 SELECT 절에만 존재하는 컬럼이나, 첫 번째 SELECT 절에 없는 컬럼을 ORDER BY에 명시하면 ORA-01791이 발생합니다. 이 경우 컬럼 별칭(alias)이나 컬럼 위치 번호로 정렬 기준을 대체해야 합니다.

3. 서브쿼리나 인라인 뷰에서 외부 쿼리의 ORDER BY가 내부 컬럼을 참조하는 경우

인라인 뷰 또는 서브쿼리를 사용할 때 외부 쿼리의 ORDER BY가 내부 뷰에서 노출되지 않은 컬럼을 참조할 경우에도 이 에러가 발생할 수 있습니다. 인라인 뷰는 외부로 노출한 컬럼만을 결과 집합으로 제공하므로, 외부 ORDER BY에서 인라인 뷰 내부에서만 사용되고 SELECT 목록에 없는 컬럼을 참조하면 Oracle이 해당 값을 찾지 못합니다.


해결 방법

원인 1 해결: DISTINCT 사용 시 ORDER BY 컬럼을 SELECT 목록에 추가

문제 쿼리:

-- ORA-01791 발생
SELECT DISTINCT department_id, first_name
FROM employees
ORDER BY salary;  -- salary가 SELECT 목록에 없음

해결 방법 1 – ORDER BY 컬럼을 SELECT에 추가:

-- 해결: salary를 SELECT 목록에 추가
SELECT DISTINCT department_id, first_name, salary
FROM employees
ORDER BY salary;

해결 방법 2 – DISTINCT 대신 GROUP BY 활용 (더 유연한 방법):

-- GROUP BY로 중복 제거 후 자유롭게 ORDER BY 사용
SELECT department_id, first_name, MAX(salary) AS max_salary
FROM employees
GROUP BY department_id, first_name
ORDER BY max_salary DESC;

원인 2 해결: UNION 집합 연산자 사용 시 ORDER BY 처리

문제 쿼리:

-- ORA-01791 발생
SELECT employee_id, first_name FROM employees
UNION
SELECT department_id, department_name FROM departments
ORDER BY department_name;  -- 첫 번째 SELECT의 컬럼 목록에 없음

해결 방법 1 – 컬럼 위치 번호로 ORDER BY 지정:

-- 두 번째 컬럼(first_name / department_name)으로 정렬
SELECT employee_id, first_name FROM employees
UNION
SELECT department_id, department_name FROM departments
ORDER BY 2;  -- 위치 번호 사용

해결 방법 2 – 첫 번째 SELECT에 별칭을 부여하고 해당 별칭으로 ORDER BY:

-- 첫 번째 SELECT에 alias 부여
SELECT employee_id AS id, first_name AS name FROM employees
UNION
SELECT department_id, department_name FROM departments
ORDER BY name;  -- 첫 번째 SELECT의 alias 사용

원인 3 해결: 인라인 뷰에서 필요한 컬럼 노출

문제 쿼리:

-- ORA-01791 발생 가능 (salary가 외부 SELECT에 없음)
SELECT emp_name
FROM (
    SELECT first_name AS emp_name, salary
    FROM employees
    WHERE department_id = 10
)
ORDER BY salary;  -- 인라인 뷰에 salary가 있지만 외부 SELECT에 없을 경우

해결 방법 – 외부 SELECT에 정렬 기준 컬럼 포함:

-- 인라인 뷰에서 salary를 외부로 노출
SELECT emp_name, salary
FROM (
    SELECT first_name AS emp_name, salary
    FROM employees
    WHERE department_id = 10
)
ORDER BY salary;

실무 팁 – DISTINCT와 ORDER BY를 동시에 사용해야 할 때 서브쿼리 활용:

-- 중복 제거 후 salary 기준 정렬이 필요한 경우
SELECT emp_name, dept_id
FROM (
    SELECT DISTINCT first_name AS emp_name, department_id AS dept_id, salary
    FROM employees
)
ORDER BY salary DESC;

예방 방법

1. SELECT 절과 ORDER BY 절을 항상 함께 검토하는 코딩 습관 유지

쿼리 작성 시 ORDER BY에 명시한 모든 컬럼이 SELECT 목록에 포함되어 있는지 작성 직후 반드시 확인하는 습관을 들이세요. 특히 DISTINCT, UNION 계열 연산자를 사용하는 쿼리는 작성 후 EXPLAIN PLAN 또는 SQL 검토 도구(SQL Developer, Toad 등)를 활용하여 실행 전에 구문 오류를 사전에 체크하는 것이 좋습니다. 팀 내 코드 리뷰 프로세스에 이 규칙을 명시적으로 포함시키면 더욱 효과적입니다.

2. 집합 연산자 사용 시 컬럼 위치 번호(Positional Notation) 또는 명확한 별칭 사용 표준화

UNION, INTERSECT, MINUS를 사용하는 쿼리에서는 ORDER BY에 컬럼 이름 대신 위치 번호(ORDER BY 1, ORDER BY 2)를 사용하거나, 첫 번째 SELECT 절에 명확한 컬럼 별칭을 부여하고 그 별칭으로 정렬하는 것을 팀 내 표준으로 정립하세요. 이렇게 하면 복잡한 집합 연산 쿼리에서도 ORA-01791 에러를 원천적으로 방지할 수 있으며, 코드 가독성도 함께 높아집니다.


관련 에러

  • ORA-00923: FROM 키워드가 예상 위치에 없을 때 발생하며, 잘못된 SELECT 절 구문과 함께 나타나는 경우가 있습니다.
  • ORA-00904: 유효하지 않은 식별자(컬럼명 오타, 존재하지 않는 컬럼 참조) 에러로, ORDER BY에 잘못된 컬럼명을 입력했을 때 ORA-01791과 혼동될 수 있습니다.
  • ORA-00907: 괄호 누락 에러로, 복잡한 서브쿼리 구조에서 인라인 뷰 관련 문제와 함께 발생하기도 합니다.
  • ORA-01785: UNION 계열 쿼리에서 ORDER BY 절의 위치가 잘못되었을 때 발생하며, ORA-01791과 유사한 상황에서 나타납니다.

DBMS 에러 코드 시리즈

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

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

댓글 남기기