WITH c ( -- 가상테이블 c c_BM_IDs -- 게시글번호 , c_Grp_M_IDs -- 그룹번호 , c_BM_UpIDs -- 상위 게시글번호 , c_BM_LoIDs -- 하위 게시글번호 , c_Lv -- 들여쓰기 , c_BM_Name -- 내용 , c_Sort_BM_IDs -- 정렬 키값 ) AS ( -- 상위 게시글번호가 0인 즉, 부모글(원글)인 데이터만 가져오기 SELECT B_i , BM_LoIDs grpM_IDs -- 그룹 M_IDs 생성 위해 필요 , BM_UpIDs , BM_LoIDs , 0 Lv -- 처음 시작이므로 레벨0 , BM_Name ------------------------------------------------------------------------------------- -- REPLICATE(채울문자, 반복횟수) : 0 또는 특정문자 채우기 함수 -- REPLICATE(채울문자, 총 자릿수 - LEN(넣을문자)) + 넣을문자 -- LEN : 자리수 반환 함수 -- CAST : 타입 변환 함수 , '_' + REPLICATE('0', 5 - LEN(B_i)) + CAST(B_i AS VARCHAR(255)) -- Sort_BM_IDs -- 채울문자 : 0 -- 총 자릿수 : 5 -- 넣을문자 : B_i FROM tBM WHERE BM_UpIDs = 0 UNION ALL -- 재귀 쿼리 실행 SELECT B_i , c_Grp_M_IDs , BM_UpIDs , BM_LoIDs , c_Lv + 1 -- Lv -- 재귀 멤버 실행될 때마다 1씩 증가 , BM_Name ----------------------------------------------------------------------------------------- , c_Sort_BM_IDs + '_' + REPLICATE('0', 5 - LEN(B_i)) + CAST(B_i AS VARCHAR(255)) FROM tBM INNER JOIN c ON c_BM_LoIDs = BM_UpIDs ) SELECT * , REPLICATE(' ', c_Lv) + c_BM_Name -- 띄어쓰기(4칸)를 c_Lv(들여쓰기)만큼 반복하고 c_BM_Name(내용)을 붙힌다. FROM c ORDER BY c_Sort_BM_IDs -- 정렬 키 값으로 오름차순 정렬
재귀 쿼리는 정의할 때 자기 자신을 참조해서 실행한다고 하는데, 그러면 코드에서 UNION ALL 다음에 오는 SELECT~INNER JOIN 부분에서 tBM 테이블과 가상테이블인 c를 JOIN 하잖아요. 이게 가상테이블 c를 정의하는 도중에 참조한다는건 알겠는데 잘 이해가 안되는 부분이.. 아직 완벽하게 정의되지 않은 c를 참조한다면 c의 범위를 어디까지 봐야되는 거죠? 그러니까 c 테이블 안에는 뭐가 들어있는거죠..?
첫번째 사진이
SELECT B_i , BM_LoIDs grpM_IDs -- 그룹 M_IDs 생성 위해 필요 , BM_UpIDs , BM_LoIDs , 0 Lv -- 처음 시작이므로 레벨0 , BM_Name ------------------------------------------------------------------------------------- -- REPLICATE(채울문자, 반복횟수) : 0 또는 특정문자 채우기 함수 -- REPLICATE(채울문자, 총 자릿수 - LEN(넣을문자)) + 넣을문자 -- LEN : 자리수 반환 함수 -- CAST : 타입 변환 함수 , '_' + REPLICATE('0', 5 - LEN(B_i)) + CAST(B_i AS VARCHAR(255)) -- Sort_BM_IDs -- 채울문자 : 0 -- 총 자릿수 : 5 -- 넣을문자 : B_i FROM tBM WHERE BM_UpIDs = 0
여기만 실행했을 때 결과 모습이고,
두번째 사진은 전체 코드 실행했을 때 결과입니다.