본문 바로가기
개발/SQL

[SQL] Column name is ambiguous 에러 처리 후기

by 핸디(Handy) 2020. 10. 5.

다음과 같은 테이블 차트를 만들었다. 

해당되는 값을 받아오기 위해서 아래와 같은 형태의 SQL을 만들었다.

SELECT TargetColumns FROM
	(
    	SELECT ROWNUM AS R, TargetColumns
        	FROM TargetDB
    )
WHERE R BETWEEN start AND start+pagesize

여기서 TargetColumns는 대상이 되는 컬럼들의 집합으로 "시도", "사고유형","사망자수" 에 해당한다.

처음에는 문제가 없었다. 하지만

TargetColumns 들이 "시도", "시도", "사고유형" 처럼 중복된 columns 이 있을 경우, 

"Column name is ambiguous error"를 내뱉으면 터졌다.

이유는 서브쿼리에서 불러온 TargetColumns과 메인 쿼리의 TargerColumns이 우리가 볼 때는 구분이 가능하나 컴퓨터가 볼 때는 모호하다는 이유였다. 

	(
    	SELECT ROWNUM AS R, TargetColumns
        	FROM TargetDB
    )

따라서 이런 경우의 해결책은 크게 2가지였다.

첫째, 사용하는 모든 컬럼에 별칭(alias)을 붙여줘 모호성을 제거하는 것이었다.  

예를 들어 "시도", "시도", "사고유형" 는 select 하는 순서에 따라 "시도_1", "시도_2", "사고유형_3"처럼

별칭을 붙여주는 것이었지만, 코드로 다시 구현하기가 귀찮았다. 그리고 성능상에도 문제가 있을 것이라 생각했다.

두 번째, 서브 쿼리 내에서는 distinct 한 컬럼만 select하고 메인쿼리에서 원하는 컬럼들을 select하는 방식이다. 

이 방식을 사용하면 서브쿼리의 코스트도 낮아지고 굳이 별칭을 쓰지 않더라도 동작할 것이라고 생각했다.

SELECT TargetColumns FROM
	(
    	SELECT ROWNUM AS R, distinctTargetColumns
        	FROM TargetDB
    )
WHERE R BETWEEN start AND start+pagesize

위의 코드와 같이 distinctTargetColumns라는 새로운 컬럼 집합을 만들어줬다.

그랬더니 잘 동작했다. 

추가적으로 지금 보는 쿼리의 경우, 오라클 SQL과 TIBERO SQL 모두 지원해야 하는 쿼리이다.

특히 ROWNUM 은 두 DB에서 약간 상이하다. 일반적으로 ROWNUM은 BETWEEN 보다는 >=, <= 등의 연산자를 쓰는 게 익숙한데, 그러면 안 먹힌다. 따라서 둘 다 사용할 수 있는 BETWEEN으로 처리해야 먹히니 유념하길 바란다.

또한 서브쿼리의 ROWNUM AS R의 경우, 위험의 소지가 있다. 특정 DB의 컬럼명이 R 이면 이것도 "ambiguous error"를 던진다.

따라서 이 부분도 수정을 했다.

SELECT TargetColumns FROM
	(
    	SELECT ROWNUM AS "ROWNUM", distinctTargetColumns
        	FROM TargetDB
    )
WHERE "ROWNUM" BETWEEN start AND start+pagesize

바로 키워드인 ROWNUM를 아예 Alias로 사용하는 것이다. 티베로와 오라클 모두 키워드를 컬럼명으로 쓰려는 경우, 못한다는 에러로 함께 안된다. 따라서 

"ROWNUM"의 별칭은 중복될 위험도 없지만 직관적인 별칭이 될 것이라는 생각으로 사용해봤다.

댓글