Lv4. 입양 시각 구하기(2) (MySQL)
링크: https://school.programmers.co.kr/learn/courses/30/lessons/59413?language=mysql
내가 작성한 코드
WITH RECURSIVE HOUR_TABLE(HOUR) AS (
SELECT 0 AS HOUR -- 초기값 설정(0시)
UNION ALL
SELECT HOUR + 1
FROM HOUR_TABLE
WHERE HOUR < 23 -- 23시가 될 때까지 1씩 증가하며 반복
)
SELECT H.HOUR, COUNT(O.ANIMAL_ID) AS COUNT
FROM HOUR_TABLE H
LEFT JOIN ANIMAL_OUTS O
ON H.HOUR = HOUR(O.DATETIME) -- 가상 데이터와 실제 데이터 시간 조인
GROUP BY H.HOUR
ORDER BY H.HOUR;
Oracle
WITH HOUR_TABLE(HOUR) AS (
-- 시작점 설정
SELECT 0 FROM DUAL
UNION ALL
-- 재귀 호출
SELECT HOUR + 1
FROM HOUR_TABLE
WHERE HOUR < 23
)
SELECT H.HOUR, COUNT(O.ANIMAL_ID) AS COUNT
FROM HOUR_TABLE H
LEFT JOIN ANIMAL_OUTS O
ON H.HOUR = TO_NUMBER(TO_CHAR(O.DATETIME, 'HH24'))
GROUP BY H.HOUR
ORDER BY H.HOUR;
문제 회고
1. 재귀 WITH절 (Recursive CTE)
- 재귀로 풀어야 한다는 방법을 몰라 계속 오류가 발생했다
- 다른 분들께서 푸신 방식들을 통해 해결 방법을 알게 되었다
- 해결 방법:
- 입양 기록이 없는 시간대도 결과에서 누락되지 않게 0시부터 23시까지의 가상 시간대 테이블을 먼저 생성해야함을 배웠다
- 초기값 설정 : SELECT 0을 통해 시작점인 0시를 설정한다
- 반복(Recursive) : UNION ALL과 SELECT HOUR + 1을 사용하여 자기 자신을 참조하며 숫자를 1씩 증가시킨다
- 정지 : WHERE 절에 종료 조건인 HOUR < 23을 명시하여 무한루프를 방지하고 문제에 맞는 필요한 범위(0~23)를 생성한다
2. LEFT JOIN
- 생성한 가상 테이블(HOUR_TABLE)을 왼쪽에 두고 실제 데이터(ANIMAL_OUTS)를 LEFT JOIN하여
기록이 없는 시간대도 결과 행에 유지되도록 처리한다
- 조인된 컬럼의 테이블인 COUNT(O.ANIMAL_ID)를 사용하여 데이터가 없는 시간대의 건수가 정확히 0이 나오도록 한다
3. 재귀 표현 방식의 차이점
- MySQL : SELECT 0 AS HOUR 처럼 내부에 별칭을 주면 (HOUR)을 생략해도 실행된다
- Oracle : WITH 테이블명(컬럼명) 형식을 지켜야한다. 컬럼명을 명시하지 않으면 재귀 부분에서 이전 단계의 값을 참조할 수 없다
: Oracle은 WITH절 안에 UNION ALL이 있으면 자동으로 재귀로 인식하여 RECURSIVE 키워드를 빼도 된다
'코딩테스트' 카테고리의 다른 글
| [26.03.30 코테/회고(MySQL/Oracle)]-저자 별 카테고리 별 매출액 집계하기 (0) | 2026.03.30 |
|---|---|
| [26.03.27 코테/회고(MySQL)]-부모의 형질을 모두 가지는 대장균 찾기 (0) | 2026.03.27 |
| [26.03.25 코테/회고(MySQL/Oracle)]-입양 시각 구하기(1) (0) | 2026.03.25 |
| [26.03.24 코테/회고(MySQL)]-없어진 기록 찾기 (0) | 2026.03.24 |
| [26.03.23 코테/회고(MySQL/Oracle)]-년, 월, 성별 별 상품 구매 회원 수 구하기 (0) | 2026.03.23 |