[MySQL] RECURSIVE 재귀 쿼리

2024. 12. 23. 17:46·코테/정리
728x90

문제를 풀던 도중 재귀 쿼리를 사용해야 하는 문제가 나왔다.

 

JAVA로는 재귀를 많이 구현해 봤는데, MySQL로 쿼리 짤 때는 사실 재귀를 많이 사용은 안 하는 것 같다.

 

WITH RECURSIVE (재귀)
WITH RECURSIVE TABLE AS(
    SELECT 1 AS i
    
    UNION ALL
    
    SELECT (i+1) AS i
    FROM TABLE
    WHERE i < 3
)
  • 재귀 쿼리를 사용하면 반드시 UNION 을 사용해줘야 한다.

 

재귀 쿼리를 만드는 순서

1. WITH RECURSIVE 가상테이블명(= 결과 테이블) 을 지정해준다.

WITH RECURSIVE TABLE AS( ... )


2. 초기 조건을 설정해준다. 

WITH RECURSIVE TABLE AS(
    SELECT 1 AS i
    
    ...
)

 

3. UNION ALL을 사용해서 반복조건과 합쳐준다.

WITH RECURSIVE TABLE AS(
    SELECT 1 AS i
    
    UNION ALL
	
    ...
)

 

4. 반복 조건을 설정해준다.

SELECT N+1 AS N
FROM TABLE
WHERE N < 3 -- break 조건문
WITH RECURSIVE TABLE AS(
    SELECT 1 AS i
    
    UNION ALL
    
    SELECT (i+1) AS i
    FROM TABLE
    WHERE i < 3
)

 

해당 코드에서는 i가 3이 되는 순간 멈춰 i가 2까지 증가하게 된다.

 

테이블 내에서 여러 컬럼을 재귀에 사용할 경우

예를들어 PATIENT 테이블이 하단과 같다고 가정했을 때,

ID TRANSLATOR_ID DATE
1 NULL 2017-01-03
2 NULL 2017-01-03
3 1 2017-01-04
4 2 2017-01-04
5 1 2017-01-05
6 3 2017-01-08
7 6 2017-01-09
8 4 2017-01-10
9 8 2017-01-15

 

감기를 4번째로 옮은 사람을 확인하고 싶을 경우

 

1. WITH RECURSIVE LIST(테이블명)에 처음 감기에 걸린 사람(=TRANSLATOR_ID IS NULL)을 지정해 준 뒤, GEN컬럼을 만들어 숫자 1을 부여해준다.

WITH RECURSIVE LIST AS(
    SELECT ID, TRANSLATOR_ID, 1 AS GEN
    FROM PATITIONS
    WHERE TRANSLATOR_ID IS NULL
    
    UNION ALL
    
    ...
)

 

PATIENT 테이블
처음 조건을 지정해준 LIST 테이블

 

2. 반복 조건을 지정해주고, break 할 조건을 지정해준다.

WITH RECURSIVE LIST AS(
    SELECT ID, TRANSLATOR_ID, 1 AS GEN
    FROM PATITIONS
    WHERE TRANSLATOR_ID IS NULL
    
    UNION ALL
    
    SELECT P.ID, P.TRANSLATOR_ID, GEN+1 AS GEN
    FROM PATITIONS P JOIN LIST L ON P.TRANSLATOR_ID = L.ID --break할 조건문
)

PATIENT 테이블
첫번째 재귀가 끝난 LIST 테이블

 

ID 3, 4, 5는 첫번째 재귀 이후 GEN = 2 로 갱신된다. 

해당 테이블을 UNION ALL 한 것이 위의 LIST 테이블!

 

 

728x90

'코테 > 정리' 카테고리의 다른 글

[JAVA] 정규식 표현으로 문자열 비교하기  (0) 2024.10.18
[JAVA] 유클리드 호제법 (최소공배수, 최대공약수)  (0) 2024.05.17
[MySQL] SUBSTR() 사용해서 문자열 뒤에서 부터 자르기  (0) 2024.05.16
[MySQL] CONV함수 사용해서 진수 변환하기  (0) 2024.05.16
[MySQL] RANK 함수  (0) 2024.04.16
'코테/정리' 카테고리의 다른 글
  • [JAVA] 정규식 표현으로 문자열 비교하기
  • [JAVA] 유클리드 호제법 (최소공배수, 최대공약수)
  • [MySQL] SUBSTR() 사용해서 문자열 뒤에서 부터 자르기
  • [MySQL] CONV함수 사용해서 진수 변환하기
DROPDEW
DROPDEW
💻 Developer | 기록하지 않으면 존재하지 않는다
  • DROPDEW
    제 2장 1막
    DROPDEW
  • 전체
    오늘
    어제
    • categories (408) N
      • App/Android (1)
      • BE (41) N
        • HTTP 웹 기본 지식 (8)
        • 스프링 입문 - 코드로 배우는 스프링 부트, 웹 .. (12)
        • 스프링부트와 JPA 활용 (8) N
        • 스프링부트 시큐리티 & JWT (0)
        • PHP (6)
      • FE·Client (23)
        • HTML (1)
        • React (19)
        • Unity (1)
      • Data (12)
        • AI (4)
        • Bigdata (6)
        • Database (1)
        • 빅데이터분석기사 (0)
      • Infra (0)
      • CS (7)
        • CS 면접 준비 (3)
      • 취준 (13)
        • 자격증·인턴·교육 (4)
        • 인적성·NCS (6)
        • 코테·필기·면접 후기 (3)
      • 코테 (270) N
        • Algorithm (222) N
        • SQL (35)
        • 정리 (13)
      • 인사이트 (27)
        • 금융경제뉴스 (7)
        • 금융용어·지식 (2)
        • 북마크 (7)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    그리디알고리즘
    최단경로
    자료구조
    누적합
    백준
    문자열
    그래프이론
    시뮬레이션
    그래프탐색
    티스토리챌린지
    오블완
    이분탐색
    브루트포스 알고리즘
    수학
    다이나믹프로그래밍
    매개변수탐색
    투포인터
    정렬
    너비우선탐색
    구현
  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.3
DROPDEW
[MySQL] RECURSIVE 재귀 쿼리
상단으로

티스토리툴바