본문 바로가기

Dev-/SQL

서브쿼리 - 로우별 카운트 추가하기(쿼리 별칭,alias 범위)

가령 1 : n 인 관계형 DB가 있을 때,

1인 테이블의 각 로우에 해당하는 n인 테이블의 수를 각각 달아줘야 할 때가 있다.



예) 게시글 (1) : 코멘트 (n) 일때




아래와 같이 표시하는 경우가 종종 있다.




- 조인 사용 -

아래와 같이 생각을 했다.

(실제 프로젝트에서는 아래 a 테이블에서 코드 테이블에 한번 더 join을 해야해서 쿼리가 엄청 길었다.)

<select id="selectList" resultType="board" >
SELECT
a.B_SEQ,

a.TITLE,

b.COMMENT_CNT
FROM
(SELECT
B_SEQ,
TITLE
FROM
BOARD) a
LEFT OUTER JOIN
(SELECT
aa.B_SEQ,
COUNT(aa.B_SEQ) COMMENT_CNT
FROM
BOARD aa,
COMMENT bb
WHERE
aa.B_SEQ = bb.B_SEQ
GROUP BY
aa.B_SEQ) b
ON
a.B_SEQ = b.B_SEQ
ORDER BY
B_SEQ DESC
LIMIT
#{pageStart}, #{perPageNum}
</select>


B_SEQ를 기준으로 1 : 1을 만족하는 두개의 테이블을 만들고 OUTER JOIN.. (NULL은 0으로)

실제 쿼리가 길었기 때문에,

짜면서도 아니라는 생각이 계속 들어 여쭤보니


아래와 같이 짜주셨는데,


내가 위와같이 비효율적으로 짠 원인는 쿼리문에서 별칭(alias)의 범위를 몰라서였다.

(코드가 길 뿐만 아니라, 시간도 많이 걸렸음)



- 서브쿼리 사용 -

<select id="selectList" resultType="board" >
SELECT
a.B_SEQ,
a.TITLE,
(SELECT COUNT(B_SEQ) FROM COMMENT WHERE B_SEQ = a.B_SEQ) AS COMMENT_CNT
FROM
BOARD a,
COMMENT b
ORDER BY
a.B_SEQ DESC
LIMIT
#{pageStart}, #{perPageNum}
</select>



글을 쓰고보니 당연한 걸 몰랐다는 생각이 든다.