세조목

SQL 예제 정리('입양 시각 구하기(2)')(24.05.21) 본문

데이터 분석 공부/SQL

SQL 예제 정리('입양 시각 구하기(2)')(24.05.21)

세조목 2024. 5. 21. 09:04

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

0시부터 23시까지 각 시간대별 입양 건수를 구하는 것이 이번 문제의 요구사항입니다.

ANIMAL_OUTS 테이블에 존재하는 시간대를 출력해보면 위 이미지에서와같이 7시부터 19시까지만 존재합니다.

문제에서는 0시부터 23시까지라고 했으니 0시~6시, 20시~23시가 추가되어야 합니다.

0부터 23이 모두 포함된 가상의 테이블을 하나 만들어서 UNION ALL로 두 개 테이블을 결합시켜주면 될 것 같습니다.

 

0부터 23이 모두 포함된 가상의 테이블을 만들기 위해서는 여러가지 방법이 있을 수 있는데요,

이번에는 재귀함수를 사용해보려고합니다.

재귀함수에서 '재귀'란 '자기 자신에게 돌아오는'이라는 의미를 가집니다.

마치 부메랑처럼요.

그래서 재귀함수는 처음부터 끝까지 갔다가 다시 처음으로 돌아와서 같은 과정을 반복하는 함수를 의미합니다.

WITH RECURSIVE NEW_TIME AS(
    SELECT 0 T
    
    UNION ALL
    
    SELECT T+1
    FROM NEW_TIME
    WHERE T < 23
)

쿼리를 한 번 살펴보겠습니다.

처음 시작은 SELECT 0 T입니다.

UNION ALL 아래 쿼리를 보시면 T에 1을 더해주는 것을 알 수 있는데요,

이 과정을 T가 23이 될 때까지(=23미만일 때) 계속해서 반복합니다.

재귀함수의 쿼리 문법은 항상 동일합니다.

WITH RECURSIVE TEST AS(
    SELECT 0 A
    
    UNION ALL
    
    SELECT A-1
    FROM TEST
    WHERE A=-7
)

예시로 작성한 쿼리문입니다.

저 틀은 유지하되 WITH RECURSIVE 옆에 적는 alias(별명)과

서브쿼리 안에 들어가는 숫자, 그리고 WHERE절 조건만 바뀌는 거죠.

 

WITH RECURSIVE NEW_TIME AS(
    SELECT 0 T
    
    UNION ALL
    
    SELECT T+1
    FROM NEW_TIME
    WHERE T < 23
)
SELECT NT.T HOUR,
       COUNT(AO.ANIMAL_ID) COUNT
FROM NEW_TIME NT LEFT JOIN ANIMAL_OUTS AO ON NT.T=HOUR(AO.DATETIME)
GROUP BY HOUR
ORDER BY HOUR;

금번 예제에서 요구하는 사항을 출력하기위해 최종적으로 작성한 쿼리는 위와 같습니다.

재귀함수로 만든 가상의 테이블과 기존 ANIMAL_OUTS 테이블을 LEFT JOIN해서

입양간 친구들의 수를 COUNT하면 됩니다.