2026.01.30(FRI)_38일차
1. 문제
문제 설명
ANIMAL_OUTS 테이블은 동물 보호소에서 입양 보낸 동물의 정보를 담은 테이블입니다. ANIMAL_OUTS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, NAME, SEX_UPON_OUTCOME는 각각 동물의 아이디, 생물 종, 입양일, 이름, 성별 및 중성화 여부를 나타냅니다.NAME | TYPE | NULLABLE |
ANIMAL_ID | VARCHAR(N) | FALSE |
ANIMAL_TYPE | VARCHAR(N) | FALSE |
DATETIME | DATETIME | FALSE |
NAME | VARCHAR(N) | TRUE |
SEX_UPON_OUTCOME | VARCHAR(N) | FALSE |
보호소에서는 몇 시에 입양이 가장 활발하게 일어나는지 알아보려 합니다. 0시부터 23시까지, 각 시간대별로 입양이 몇 건이나 발생했는지 조회하는 SQL문을 작성해주세요. 이때 결과는 시간대 순으로 정렬해야 합니다.
예시
SQL문을 실행하면 다음과 같이 나와야 합니다.
HOUR | COUNT |
0 | 0 |
1 | 0 |
2 | 0 |
3 | 0 |
4 | 0 |
5 | 0 |
6 | 0 |
7 | 3 |
8 | 1 |
9 | 1 |
10 | 2 |
11 | 13 |
12 | 10 |
13 | 14 |
14 | 9 |
15 | 7 |
16 | 10 |
17 | 12 |
18 | 16 |
19 | 2 |
20 | 0 |
21 | 0 |
22 | 0 |
23 | 0 |
본 문제는 Kaggle의 "Austin Animal Center Shelter Intakes and Outcomes"에서 제공하는 데이터를 사용하였으며 ODbL의 적용을 받습니다.
2. 풀이
SELECT fht.HOUR, IFNULL(fao.COUNT, 0) 'COUNT'
FROM (WITH RECURSIVE ht AS (
SELECT 0 AS 'HOUR'
UNION ALL
SELECT HOUR + 1
FROM ht
WHERE HOUR < 23)
SELECT *
FROM ht) fht LEFT OUTER JOIN (SELECT ao.HOUR, COUNT(ao.ANIMAL_ID) 'COUNT'
FROM (SELECT ANIMAL_ID, HOUR(DATETIME) 'HOUR'
FROM ANIMAL_OUTS) ao
GROUP BY ao.HOUR) fao
ON fht.HOUR = fao.HOUR;HOUR | COUNT |
0 | 0 |
1 | 0 |
2 | 0 |
3 | 0 |
4 | 0 |
5 | 0 |
6 | 0 |
7 | 3 |
8 | 1 |
9 | 1 |
10 | 2 |
11 | 13 |
12 | 10 |
13 | 14 |
14 | 9 |
15 | 7 |
16 | 10 |
17 | 12 |
18 | 16 |
19 | 2 |
20 | 0 |
21 | 0 |
22 | 0 |
23 | 0 |
[참고] 재귀 CTE (WITH RECURSIVE)
쿼리 안에서 자기 자신을 반복 호출해서 행을 만들어내는 임시 테이블
1) 한 줄 정의
SELECT 결과를 다시 SELECT의 입력으로 사용해 반복 처리하는 SQL 문법
2) 왜 쓰나?
- 연속된 숫자 생성 (0~23, 날짜 범위 등)
- 계층 구조 조회 (부모–자식, 조직도)
- 반복 계산이 필요한 경우
3) 기본 구성 (2파트 구조)
① Anchor member (시작값)
- 재귀의 출발점
- 처음에 딱 한 번 실행
② Recursive member (반복 부분)
- 이전 결과를 다시 사용
- 조건이 거짓이 될 때까지 반복
이 둘을
UNION ALL로 연결4) 실행 흐름 (개념)
① anchor 실행 → 결과 생성
② recursive 실행 → 이전 결과 기반으로 새 행 생성
③ 조건 검사
④ 반복
⑤ 조건 실패 → 종료→ 내부적으로는 반복문처럼 동작
5) 꼭 지켜야 할 규칙 ⚠️
- 종료 조건이 반드시 필요 (무한 루프 방지)
UNION ALL사용 (중복 제거 불필요)
- 재귀 쿼리에서 CTE 이름을 FROM 절에 사용
6) 예시
WITH RECURSIVE numbers AS (
-- ① 시작값 (anchor)
SELECT 0 AS n
UNION ALL
-- ② 반복 부분 (recursive)
SELECT n + 1
FROM numbers
WHERE n < 3
)
SELECT *
FROM numbers;WITH RECURSIVE ht AS (
SELECT 0 AS 'HOUR'
UNION ALL
SELECT HOUR + 1
FROM ht
WHERE HOUR < 23
)
SELECT *
FROM ht;Share article