티스토리 뷰

오라클에서 ms-sql처럼 TOP 1을 뽑고자 할 때에는, ROWNUM을 써야 한다.
근데 ROWNUM은 어떻게든 subquery를 이용할 수 밖에 없어,
SELECT 구문에서 다른 테이블의 top 1을 조인하여 가져오고자 할 때엔,
2단계 서브쿼리에서 참조하고자 하는 테이블의 값이 참조되지 않아 답답할 때가 있다.

예를 들어,
model 테이블의 모델 정보를 가져오는데 version 테이블에서 해당 모델의 최신 version을 함께 뽑아오고자 한다.

model                  1:n           version
-----------                         ----------
modelid (PK)                        versionid(PK)       
name (UK)                           modelid(FK)
detail                                  ver
                                          regdate



위와 같은 테이블이 있고,
해당 모델의 최신 버전은 ORDER BY regdate DESC, ver DESC 하여 구한다고 하자.

하여, 아래와 같은 쿼리를 만들었다.

SELECT
    name,
    (
        SELECT ver
        FROM (
            SELECT ver, ROW_NUMBER() OVER (ORDER BY regdate DESC, ver DESC) AS rnum
            FROM verion
            WHERE modelid = a.modelid)
        WHERE rnum = 1) AS ver
FROM model


하지만 이 쿼리는 작동하지 않는다.
2단계 subquery의 경우, 참조하는 테이블의 컬럼을 가져올 수 없기 때문이다. (빨간색 참조)


하여, TOP 1을 구하는 부분을 MAX - KEEP 구문을 사용하여 바꿔보았다.

SELECT
    name,
    (SELECT MAX(versionid) KEEP (DENSE_RANK FIRST ORDER BY ver_date DESC, version DESC)
     FROM version
     WHERE modelid = a.modelid)
FROM model


versionid를 구하되, KEEP 이하 구문을 기준으로 구하는 것이다~
훨씬 깔금해졌다.

KEEP 키워드에 대해선 좀더 알아보아야겠다~

반응형
댓글
공지사항