SELECT
A.ID
, A.FIRST_NAME
, A.SECOND_NAME
, A.LAST_NAME
, A.AGE
, B_1.NAME
, B_2.NAME
, B_3.NAME
FROM TABLE_1 A
INNER JOIN TABLE_2 B_1 ON A.FIRST_NAME = B_1.NAME
INNER JOIN TABLE_2 B_2 ON A.SECOND_NAME = B_2.NAME
INNER JOIN TABLE_2 B_3 ON A.LAST_NAME = B_3.NAME
위와 같은 쿼리는 B테이블이 A테이블의 여러 칼럼과 연관이 있어 여러번 조인을 합니다.
간단한 쿼리의 경우에는 간편히 끝낼수도 있지만 어떤 문서에 필요한 이름이 10~20개를 넘어가는 경우 이렇게 계속해서 조인하다간 내가 만든 쿼리도 보기가 불편하고 _1, _2 숫자를 붙이다 보니 뭐가 뭔지 헷갈리게 됐습니다.
그래서 다른 방법으로 조인을 최소화하고 반복적으로 사용되는 테이블을 한번만 프로젝션하거나 FUNCTION을 통해서 쿼리문을 간단히 만들기로 했습니다.
WITH B AS (
SELECT * FROM TABLE_2
)
SELECT
A.ID
, A.FIRST_NAME
, A.SECOND_NAME
, A.LAST_NAME
, A.AGE
, (SELECT B.NAME FROM B WHERE B.NAME = A.FIRST_NAME) AS B_1.NAME
, (SELECT B.NAME FROM B WHERE B.NAME = A.SECOND_NAME) AS B_2.NAME
, (SELECT B.NAME FROM B WHERE B.NAME = A.LAST_NAME) AS B_3.NAME
FROM TABLE_1 A
WITH 절을 이용해서 반복적으로 조인되던 테이블을 상단에 분리시킵니다.
오라클에서 FUNCTION은 아래의 모양으로 만듭니다.
CREATE OR REPLACE FUNCTION GET_NAME_FROM_TABLE_2(p_name VARCHAR2)
RETURN VARCHAR2
IS
v_name TABLE_2.NAME%TYPE;
BEGIN
SELECT NAME INTO v_name
FROM TABLE_2
WHERE NAME = p_name;
RETURN v_name;
END;
FUNCTION에 A테이블의 칼럼을 넣게 되면 자동으로 조건절을 통해 조회가 이루어집니다.
SELECT
A.ID
, A.FIRST_NAME
, A.SECOND_NAME
, A.LAST_NAME
, A.AGE
, GET_NAME_FROM_TABLE_2(A.FIRST_NAME) AS B_1.NAME
, GET_NAME_FROM_TABLE_2(A.SECOND_NAME) AS B_2.NAME
, GET_NAME_FROM_TABLE_2(A.LAST_NAME) AS B_3.NAME
FROM TABLE_1 A;