본문 바로가기
MYSQL/프로그래머스 LV04

입양 시각 구하기(2)

by 수스리 2025. 3. 27.

 

WITH RECURSIVE cte_name AS (
    -- 초기 쿼리 (기본 케이스)
    SELECT initial_values
    
    UNION [ALL]
    
    -- 재귀 쿼리 (재귀 케이스)
    SELECT values FROM cte_name WHERE condition
)
SELECT * FROM cte_name;

https://school.programmers.co.kr/learn/courses/30/lessons/59413

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

문제

보호소에서는 몇 시에 입양이 가장 활발하게 일어나는지 알아보려 합니다. 0시부터 23시까지, 각 시간대별로 입양이 몇 건이나 발생했는지 조회하는 SQL문을 작성해주세요. 이때 결과는 시간대 순으로 정렬해야 합니다.

WITH RECURSIVE TEMP AS(
    SELECT 0 as HOUR
    UNION ALL
    SELECT HOUR + 1 FROM TEMP WHERE HOUR < 23
),
TEMP2 AS(
    SELECT 
        HOUR(DATETIME) AS HOUR2, COUNT(*) AS COUNT
    FROM    
        ANIMAL_OUTS
    GROUP BY
        HOUR(DATETIME)
)
SELECT
    HOUR, IF(COUNT IS NULL, 0 , COUNT) AS COUNT 
FROM
    TEMP T
LEFT JOIN
    TEMP2 T2 ON T.HOUR = T2.HOUR2
ORDER BY
    HOUR

이 문제는 애초에 풀 수가 없는 문제였다. 내가 처음보는 문법 혹은 배웠는데 기억이 안나는 문법이 나왔기 때문이다.  

WITH RECRUSIVE 는 재귀쿼리를 돌릴 수 있는 문법이다. 기본 구조는 다음과 같다.

WITH RECURSIVE cte_name AS (
    -- 초기 쿼리 (기본 케이스)
    SELECT initial_values
    
    UNION [ALL]
    
    -- 재귀 쿼리 (재귀 케이스)
    SELECT values FROM cte_name WHERE condition
)
SELECT * FROM cte_name;

아래는 예제

WITH RECURSIVE numbers AS (
    SELECT 1 AS n  -- 초기값
    UNION ALL
    SELECT n + 1 FROM numbers WHERE n < 10  -- 1씩 증가, 10에서 중지
)
SELECT n FROM numbers;  -- 1부터 10까지 출력

이러면 1부터 10까지 출력할 수 있다.

본 코드에서 1부터 23까지 출력후 LEFT JOIN을 한다. 겹치지 않는 녀석들은 0으로두고 출력하면 된다. 
아는데 까먹어서 틀린거는 화나는데 몰라서 틀리는 건 그렇지 않다. 다행이다(?)