
아직 가야할 길은 많지만 내가 이해한 부분까지만이라도 기록하기 위해
반복필드를 작성하게 될 때가 있다. 예를 들어 아래와 같은 경우이다.
직장명1: A 엔터테인먼트
재직기간1: 1999.01.01 ~ 2000.12.31
재직자수1: 80직장명2: B 엔터테인먼트
재직기간2: 2001.01.01 ~ 2002.12.31
재직자수2: 90
...
흔히 이력서 쓸 때 추가, 삭제 버튼으로 항목을 가감하는 부분이라 생각할 수 있다.
나같은 초짜는 이런 데이터로 전산파일을 기획할 시 Union All만 떠올렸다.
하다못해 반복필드가 20개 짜리인 경우에도 프로시져를 위해 SubLime을 켜서 주구장창 Union All로 이어붙인 기억이 있다.
Select
[연번], [직장명], [재직기간], [재직자수]
From (
-- 무한 Union All의 향연
)
그러던와중 시니어 짱발자분의 코드를 통해 Cross Apply와 Values로 활용하는 법을 접하게 되었다.
Select
A.SomeColumn
,CA.*
From ATable A
Inner Join BTable B On A.ID = B.ID
Cross Apply (Values
(1, JobName1, CareerDate1, JobMemCnt1)
,(2, JobName2, CareerDate2, JobMemCnt2)
) CA ('연번','직장명','재직기간','재직자수')
수많은 조인과 복잡한 조건이 걸린 프로시져였지만 얼추 위와 같은 코드로 작성할 수 있을 것 같다.
우선 나같은 초짜는 Values가 어떻게 쓰인건지도 짚고 넘어가줘야한다.
SELECT의 FROM절에서도 VALUES를 활용해 가상 테이블을 만들 수 있다.
Select TMP.* From (Values (1,2), (3,4), (5,6)) TMP ('A', 'B');
위의 코드는 (A,B) 컬럼에 각각 (1,2), (3,4), (5,6) 행이 들어가게 된다는 것.
쉽고 얕게 말하자면 Inner Join과 동일한 결과를 반환한다.
Select
*
From ATable A
Inner Join BTable B On A.ID = B.ID
-- 위아래 모두 동일한 결과 반환
Select
*
From ATable A
Cross Apply (Select * From BTable Where A.ID = B.ID) B
외부 테이블의 컬럼을(ATable) 인자로 넘길 수 있는 장점이있다.
고로 짱발자 분의 코드에서는 Inner Join한 다양한 컬럼들을 인자로 넘기고 그려낼 수 있었던 것.
그러면 굳이 Cross Apply를 써야할까?
라는 생각을 하고 있을 때 짱발자 분이 이 글을 공유 주셨다: 링크
확실히 조인을 통해 불필요한 데이터까지 가져오기 전 쳐내니 성능이 월등히 좋아진다.