본문 바로가기
SQL

[SQL] 프로그래머스 입양시각 구하기 (2)

by 다람이도토리 2021. 9. 21.

프로그래머스 SQL 연습문제의 레벨4 문제이자, 마지막 수문장 정도 되는 문제.

다른 문제들에 비해서는 그래도 꽤 어려운 문제로, 많이 배우고 설명을 듣고 해당 내용을 정리해보았다.

문제 출처
https://programmers.co.kr/learn/courses/30/lessons/59413

문제의 난점

단순히 group by 시간해서, 풀만한 그런 문제가 아니다.

0시~23시 각 시간별로 입양이 몇번 일어났는지를 알아내야 하나, 문제는 0번인 시간대도 출력해야 한다.

문제 발상

이를 위해서는 0시~23시 시간만 적힌 테이블 하나랑,  입양 횟수를 시간대로 정리한 테이블 하나를 left join시키면 될 것이다. 하지만 어떻게 0시~23시를 만들어 줄 것인가? 이게 해당 문제의 포인트다.

풀이방법(Mysql)

방법(1)

with이라는 구문이 있다. 이는 subquery와 유사하나, subquery는 해당 지역에서 한 번만 테이블을 만들어 가져오는 구조라면, with은 아예 반복적으로 사용 가능한 가상의 테이블을 하나 만들어준다고 생각하면 된다.

with을 이용한 풀이는 다음과 같다.

with recursive cte(hour) as
(
        select 0
        union all
        select hour +1 from cte where hour<23
)
SELECT
	cte.hour, 
    count(animal_outs.animal_id) as count
FROM
	cte
    left join animal_outs On cte.hour = hour(animal_outs.datetime)
GROUP BY
	hour
ORDER BY
	hour

방법(2)

with을 쓰지 않는 방법으로 새로 배운 방법이다..  반복적으로 돌릴 수 있는 변수를 만드는 방법이다.

set @rownum := -1;
select
    @rownum := @rownum+1 as hour,
    (select count(*) from animal_outs where hour(datetime) = @rownum) as cnt
from 
    animal_outs
where 
    @rownum < 23

:=을 통해 변수가 만들어진다고 보면 되는데, 해당 기능은 +1을 계속 반복적으로 시행하게 되는 기능이다. 
즉 , where에서 stopper 조건을 걸어주지 않으면 안 된다.