프로그래머스 문제 중 하나인 입양 시각 구하기(2) 풀이를 정리합니다.
해당 문제는 프로그래머스에 가입이 되어 있다면 이 페이지에서 직접 풀어볼 수 있다.
문제 정보
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문을 작성해라. 이때 결과는 시간대 순으로 정렬해야 한다.
정답 코드
먼저 정답은 아래와 같다.
1 | SELECT |
문제 해설
일단 문제를 크게 3개로 나눠서 생각했다.
- 시간대 필드 생성 쿼리
- 입양 건수를 세는 쿼리
- 최종 도출 쿼리
각각의 쿼리를 분석해보자.
시간대 필드 생성 쿼리
위 문제는 데이터가 없는 시간대도 쿼리 상에서 결과를 같이 도출해야 한다. 예를 들어 1시에 입양 건수가 없어도 이를 레코드로 가져와야 한다. 따라서 0 ~ 23을 레코드로 가지는 필드를 생성한다. 해당 쿼리는 아래와 같다.
1 | SELECT |
DUAL
은 함수에 따른 결과값을 도출하고 싶을 때 사용하는 임시 더미 테이블이다. 변수 N
에 -1
을 할당하여 더미 테이블을 생성한다. 생성된 더미 테이블은 아래와 같다.
@N:=-1 |
---|
-1 |
위 더미와 ANIMAL_OUTS을 조인한 결합 테이블에서 1씩 더해지는 변수 N
을 조회하여 가져온다. LIMIT
으로 24로 제한을 두어 0부터 23까지 레코드가 도출되도록 한다.
위 쿼리의 결과는 아래와 같다.
HOUR |
---|
0 |
1 |
… |
22 |
23 |
입양 건수를 세는 쿼리
이 쿼리는 ANIMAL_ID의 개수를 확인하여 각 시간별로의 입양 건수를 가져온다. 해당 쿼리는 아래와 같다.
1 | SELECT |
ANIMAL_OUTS
라는 테이블에는 DATETIME 타입의 날짜 및 시간 필드가 있다. 해당 필드에서 HOUR()
을 사용하여 시간만을 도출하고 이를 GROUP BY
대상으로 사용하여 각 시간대별로 입양 건수가 합쳐져서 반환될 수 있도록 한다. 다음으로 ORDER BY
하여 시간대 별로 정렬한다. 위 쿼리의 결과는 아래와 같다.
HOUR | COUNTS |
---|---|
7 | 3 |
8 | 1 |
… | … |
18 | 16 |
19 | 2 |
위 결과에서 입양 건수가 있는 시간대만 반환되는 것을 볼 수 있다.
최종 도출 쿼리
이제 위 두개의 쿼리를 하나로 합쳐서 가져오면 된다. 먼저 쿼리의 구조를 살펴보자.
1 | SELECT |
위 쿼리는 두 테이블의 HOUR 필드를 기준으로 LEFT JOIN
하여 시간 테이블인 T
의 HOUR 필드와 입양건수 테이블인 D
의 COUNT 필드의 값을 가져온다. 또한 T
의 HOUR 필드 값이 D
에 없는 경우 발생하는 NULL은 IFNULL()
을 통해 0으로 변경한다.
위 쿼리의 결과는 아래와 같으며, 이는 정답 예시와 동일하다.
HOUR | COUNT |
---|---|
0 | 0 |
1 | 0 |
… | … |
22 | 0 |
23 | 0 |