다음과 같은 테이블 차트를 만들었다.
해당되는 값을 받아오기 위해서 아래와 같은 형태의 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"의 별칭은 중복될 위험도 없지만 직관적인 별칭이 될 것이라는 생각으로 사용해봤다.
댓글