MSSQL 재귀 쿼리에 대해서 질문있습니다. 0 1 742

by ALSWL MSSQL [2020.11.04 18:03:08]


22.PNG (9,960Bytes)
23.PNG (52,274Bytes)

		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

여기만 실행했을 때 결과 모습이고,

 

두번째 사진은 전체 코드 실행했을 때 결과입니다.

by 마농 [2020.11.05 10:11:13]

UNION 상단에서 1 레벨 정보를 가져오고
UNION 하단에서 1 레벨 정보와 조인하여 2레벨 정보를 생성합니다.
이렇게 생성된 2레벨을 가지고 다시 또 3레벨을 생성합니다.
이렇게 차근 차근 단계를 밟아 나갑니다.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입