본문 바로가기
SQL 문제 풀기/1. 프로그래머스 SQL : 2023.12.17~2024.2.29

<프로그래머스 37> 입양 시각 구하기1(Lv.2)

by HYEHYE_SON 2024. 1. 22.
728x90

 

프로그래머스에서 제공하는 SQL문제 매일 풀기 챌린지


문제 설명 

ANIMAL_OUTS 테이블은 동물 보호소에서 입양 보낸 동물의 정보를 담은 테이블입니다. ANIMAL_OUTS 테이블 구조는 다음과 같으며, ANIMAL_IDANIMAL_TYPEDATETIMENAMESEX_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

문제

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

 

예시

SQL문을 실행하면 다음과 같이 나와야 합니다.

HOUR COUNT
9 1
10 2
11 13
12 10
13 14
14 9
15 7
16 10
17 12
18 16
19 2

 

 

본 문제는 Kaggle의 "Austin Animal Center Shelter Intakes and Outcomes"에서 제공하는 데이터를 사용하였으며 ODbL의 적용을 받습니다.


오라클 정답

select extract(hour from cast(datetime as timestamp)) as hour, count(*) as count
    from animal_outs
    where extract(hour from cast(datetime as timestamp)) between '9' and '19'
    group by extract(hour from cast(datetime as timestamp))
    order by hour;

 

오라클 정답 해설하기

datetime 컬럼의 datetype은 결과 출력 시
<년-월-일 시간:분:초>
형식으로 출력된다.
따라서 해당 값에서 시간만 추출하여 hour컬럼을 만들어 줘야 한다.

hour를 추출할 수 있는 함수는 
to_char()와 extract() 함수가 있다.

하지만 to_char(datetime, 'HH24')로 시간을 추출하면,
한자리 수의 시간이 0과 함께 출력되어 09로 출력된다.

문제에 제시된 예를 보면,
0 없이 9만 출력되는 것을 확인할 수 있다.

따라서 이 문제에서는 EXTRACT함수를 사용해줘야 한다.
이 함수의 문법은 아래와 같다.

 

● EXTRACT () 함수

EXTRACT함수는 날짜형 data type을 가진 특정 데이터로부터

원하는 날짜 정보만 추출하여, 새로운 컬럼의 형태로 추출해주는 함수이다.

select EXTRACT( [날짜요소] FROM [특정컬럼B] ) as [별칭]
    from [테이블명A];

특정 테이블 A에 있는 컬럼 중 날짜 변수가 담긴 특정컬럼B로부터 

원하는 날짜요소를 추출하여 새로운 컬럼으로 추출해 주는 쿼리 문이다.

- 날짜요소 : YEAR, MONTH, DAY, HOUR, MINUTE, SECOND

(자세한 예시와 실습은 추후 게시물로 업로드할 예정)

하지만 주의해야 할 점은, 
날짜형 데이터 타입 중 DATETIME 타입은
EXTRACT를 활용한 HOUR, MINUTE, SECOND 추출은 할 수 없다는 것이다.

Q. 그럼 어떻게 추출해야 하는가?
DATETIME의 형식을 TIMESTAMP로 일시적으로 변경해 주면 된다. 
그럴 때 사용할 수 있는 함수는 CAST() 함수이다.

 

● CAST() 함수

CAST함수는 데이터 형식을 실시간으로 변환해 주는 함수이다.

문법은 아래와 같다.

CAST( [형변환할 대상 컬럼] as [변환하고자 하는 DATA TYPE] )

 

CAST함수는 많이 사용하지는 않지만,

데이터 타입 불일치로 인하여 발생하는 에러를 방지할 수 있다.

# 1. SELECT절
위의 설명을 토대로 
HOUR컬럼은 가공하여 만들어내야 한다.

EXTRACT( HOUR FROM CAST(DATETIME AS TIMESTAMP)) AS HOUR

로 hour를 만들어주고, 시간대별 건수를 구하는 것이므로 count 하는 컬럼을 만들어 준다.


# 2. FROM절
데이터를 가져올 테이블 명 ANIMAL_OUTS를 기입해 준다.


# 3. WHERE절
HOUR가 09:00~19:59분 사이라는 조건이 있어야 하므로,
BETWEEN.. AND를 사용하여 조건을 만들어 준다.

[컬렴명] BETWEEN [시작값] AND [마지막 값]

추가적으로 시작값과 마지막 값은 포함되는 값임을 알고 있어야 한다.
(WHERE절에서는 별칭을 사용할 수 없기 때문에
HOUR를 추출하는 문법을 그대로 가져와서 사용한다)


# 4. GROUP BY 절
시간대 별 건수를 구해야 하기 때문에
시간대를 각자 GROUP으로 묶어줘야 한다.
(마찬가지로 별칭을 사용할 수 없어
HOUR를 추출하는 문법을 그대로 가져온다.)


# 5. ORDER BY절
시간대를 기준으로 ASC 하게 정렬하는 것이므로 
HOUR ASC를 기입하는데,
ASC는 기본값이므로 생략이 가능하다.
(ORDER BY절에서는 별칭 사용이 가능하다)

 

 

MySQL 정답

select hour(datetime) as hour, count(*) as count
    from animal_outs
    where hour(datetime) between '9' and '19'
    group by hour(datetime)
    order by hour;

 

MySQL 정답 해설하기

# 1. SELECT절

● HOUR( [컬럼명] )
MySQL은 hour() 함수를 사용하여 시간을 추출할 수 있다.
이때 추출되는 형식이 24시간 형식이며,
한자리 수가 출력될 때는 0과 함께 출력되는 것이 아니라
예시문과 같이 오전 9시면 9만 출력된다.

따라서 hour(datetime)을 사용하여 시간을 추출하고,
시간대별 입양 건수를 구하는 것이므로 count(*)를 이용해 준다.


# 2. FROM절
데이터를 가져올 테이블 명 animal_outs를 기입해 준다.


# 3. WHERE절
[컬렴명] BETWEEN [시작값] AND [마지막 값]
을 이용하여 오전 9 ~ 오후 19시라는 조건을 준다.
이때 시작값과 마지막 값은 포함된다.


# 4. GROUP BY 절
시간대 별 건수를 구해야 하기 때문에
시간대를 각자 GROUP으로 묶어줘야 한다.
(마찬가지로 별칭을 사용할 수 없어
HOUR를 추출하는 문법을 그대로 가져온다.)


# 5. ORDER BY절
시간대를 기준으로 ASC 하게 정렬하는 것이므로 
HOUR ASC를 기입하는데,
ASC는 기본값이므로 생략이 가능하다.
(ORDER BY절에서는 별칭 사용이 가능하다)

 

 

결과 출력

 

 

 

출처 : 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges

반응형