관리 메뉴

Rootable의 개발일기

프로그래머스 SQL 풀이 - 입양 시각 구하기(2) 본문

프로그래머스 - SQL Kit

프로그래머스 SQL 풀이 - 입양 시각 구하기(2)

dev-rootable 2023. 5. 24. 18:39

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

 

프로그래머스

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

programmers.co.kr

 

문제 설명

ANIMAL_OUTS 테이블은 동물 보호소에서 입양 보낸 동물의 정보를 담은 테이블입니다. ANIMAL_OUTS 테이블 구조는 다음과 같으며, ANIMAL_IDANIMAL_TYPEDATETIMENAMESEX_UPON_OUTCOME는 각각 동물의 아이디, 생물 종, 입양일, 이름, 성별 및 중성화 여부를 나타냅니다.

 

출처 : 프로그래머스

 

문제

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

 

예시

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

 

출처 : 프로그래머스

 

풀이

이 문제는 프로그래머스 SQL 고득점 Kit 문제 중 가장 어려웠다.

 

조건에 부합하지 않는 레코드는 결과에 등장하지 않는다. 하지만 이 문제에서는 0 ~ 23시 시간 별로 카운팅했을 때, 데이터 셋에 없는 시간이라도 결과에 무조건 등장하도록 해야 했다. 이것을 보고 Program Language의 반복문을 SQL에서 비슷하게 구현하면 풀 수 있을 것 같았다.

 

반복문은 초기값이 있고 범위가 있다. 그리고 증감 연산자를 통해 다음 값을 결정한다. 이 3가지를 SQL로 구현해보자.

 

1. SQL에서 변수를 선언할 때, @변수를 사용한다. 

 

2. (⭐)반복문의 Body는 무엇이 되어야 할까

 

원하는 시간 조건에서 카운팅한 결과를 얻어야 하므로 Main 절이 반복문의 껍데기가 되고 스칼라 쿼리(SELECT 서브 쿼리)가 반복문의 Body가 되면 된다. Body의 내용은 원하는 시간 조건 별 COUNT 집계 결과다. GROUP BY를 하게 되면 NULL값은 제외시키므로, 변수를 통해 Main 절로부터 범위 내 값(HOUR)을 WHERE 조건문에서 반복해서 받도록 한다.

 

3. (⭐)반복문

 

 - SET을 통해 초기값 설정 (초기값은 0부터 해야 될 것 같지만, 첫 증감 결과가 시작 값이 되므로 -1로 한다.)

 - SELECT에서 (변수 := 변수 + 1)을 하여 1씩 증가하도록 한다. = 은 비교연산자이므로 := 대입연산자를 써야 한다.

 - 마지막으로 Main 절의 WHERE의 범위는 23 미만으로 한다. 23까지 출력해야 하므로 22일 때 증감 연산자를 수행한 결과(=23)까지만 출력해야 한다.

 

정답 코드

SET @HOUR = -1;
SELECT (@HOUR := @HOUR + 1) as HOUR,
(SELECT COUNT(HOUR(DATETIME)) 
 FROM ANIMAL_OUTS
 WHERE HOUR(DATETIME) = @HOUR) as COUNT
FROM ANIMAL_OUTS
WHERE @HOUR < 23