📌 고정 게시글

📢 공지합니다

이 게시글은 메인 페이지에 항상 고정되어 표시됩니다.

최코딩의 개발

서브쿼리와 조인 전략 본문

회사/갤럭시아머니트리

서브쿼리와 조인 전략

seung_ho_choi.s 2026. 1. 19. 15:54
728x90

오늘은 회사에서 서브쿼리와 JOIN에 대해 공부하라는 과제를 받아서, 실제 업무에서 마주친 문제를 중심으로 정리해봤다.

문제 상황

가맹점 게시글 목록을 조회할 때 작성자 이름을 함께 보여줘야 한다. 그런데 게시글의 TARGET_TYPE 값에 따라 작성자가 서로 다른 테이블에 저장되어 있다:

  • TARGET_TYPE = 'customerAdmin' → NTCFG_AGENTUSER 테이블 조회
  • TARGET_TYPE = 'masterAdmin' → NTEMP_ADMINUSER 테이블 조회

같은 "작성자 이름"이지만 데이터 출처가 다른 상황이다. 이걸 어떻게 한 번의 쿼리로 가져올 수 있을까?

 

해결 방법 1: 서브쿼리 방식으로 구현

- JOIN 없이 CASE + 상관 서브쿼리 사용

- 행마다 필요한 테이블만 조회

SELECT *
FROM (
    SELECT
        ROWNUM AS RN,
        t.*
    FROM (
        SELECT
            get_code_name('CshCategory', B.CATEGORY) AS CATEGORY,
            B.TITLE,
            B.VIEW_COUNT,
            B.CREATED_AT,
            B.BOARD_ID,
            CASE
                WHEN B.TARGET_TYPE = 'customerAdmin' THEN
                    (
                        SELECT ca.AGENTUSER_NAME
                        FROM NTCFG_AGENTUSER ca
                        WHERE ca.AGENTUSER_ID = B.ADMINUSER_ID
                    )
                WHEN B.TARGET_TYPE = 'masterAdmin' THEN
                    (
                        SELECT ma.ADMINUSER_NAME
                        FROM NTEMP_ADMINUSER ma
                        WHERE ma.ADMINUSER_ID = B.ADMINUSER_ID
                    )
            END AS WRITER_NAME
        FROM TEST_CSH_BOARD B
        WHERE SUBSTR(B.CREATED_AT, 1, 8)
              BETWEEN '20260119' AND '20260119'
        ORDER BY B.BOARD_ID DESC
    ) t
    WHERE ROWNUM <= 15
)
WHERE RN >= 1;

 

해결 방법 2: JOIN 방식으로 구현

- 두 사용자 테이블을 모두 LEFT JOIN

- CASE WHEN으로 작성자 이름 분기

SELECT
    RN,
    CATEGORY,
    TITLE,
    VIEW_COUNT,
    CREATED_AT,
    BOARD_ID,
    WRITER_NAME
FROM (
    SELECT
        ROWNUM AS RN,
        t.*
    FROM (
        SELECT
            get_code_name('CshCategory', B.CATEGORY) AS CATEGORY,
            B.TITLE,
            B.VIEW_COUNT,
            B.CREATED_AT,
            B.BOARD_ID,
            CASE
                WHEN B.TARGET_TYPE = 'customerAdmin' THEN CA.AGENTUSER_NAME
                WHEN B.TARGET_TYPE = 'masterAdmin' THEN MA.ADMINUSER_NAME
            END AS WRITER_NAME
        FROM TEST_CSH_BOARD B
        LEFT JOIN NTCFG_AGENTUSER CA
            ON B.TARGET_TYPE = 'customerAdmin'
           AND CA.AGENTUSER_ID = B.ADMINUSER_ID
        LEFT JOIN NTEMP_ADMINUSER MA
            ON B.TARGET_TYPE = 'masterAdmin'
           AND MA.ADMINUSER_ID = B.ADMINUSER_ID
        WHERE SUBSTR(B.CREATED_AT, 1, 8)
              BETWEEN '20260119' AND '20260119'
        ORDER BY B.BOARD_ID DESC
    ) t
    WHERE ROWNUM <= 15
)
WHERE RN >= 1;

 

이렇게 2가지 방식으로 데이터를 가져오는 방식이 있다. 

 

서브쿼리와 JOIN의 차이는 단순한 문법 선택의 문제가 아니라,

데이터를 어떻게 다룰 것인가에 대한 관점의 차이이다.

 

즉, 결과 집합에서 행(row)을 줄이는 데 초점을 둘 것인지,

아니면 열(column)을 확장해 데이터를 결합할 것인지의 차이라고 볼 수 있다.

 

JOIN은 여러 테이블의 데이터를 결합해 조회 결과를 구성하는 데 적합하다.
필요한 컬럼들을 한 번에 가져와 화면이나 리포트에 보여줘야 하는 경우,
JOIN은 결과 구조가 명확하고 활용도가 높다.

 

반면 서브쿼리는 다른 테이블의 데이터를 직접 결합하기보다는,
조건을 계산하거나 존재 여부를 판단해 불필요한 행을 사전에 걸러내는 데 목적이 있다.
특히 대량의 데이터 중 특정 조건을 만족하는 대상만 추려내는 상황에서는
서브쿼리가 쿼리의 의도를 더 분명하게 드러내며, 실행 계획상으로도 효율적인 경우가 많다.

 

따라서 조회 결과를 어떤 형태로 만들고 싶은지,
즉 데이터를 “붙일 것인지” 아니면 “줄일 것인지”를 기준으로
JOIN과 서브쿼리를 선택하는 것이 가장 합리적인 접근이다.

 

 

728x90

'회사 > 갤럭시아머니트리' 카테고리의 다른 글

[2부] CS 과제 공부하기  (0) 2026.01.22
[1부] CS 과제 공부하기  (0) 2026.01.21