프로그래머스 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 조건을 걸어주지 않으면 안 된다.
'SQL' 카테고리의 다른 글
[SQLD] Grouping 함수, Window 함수 정리 (1) (1) | 2023.12.27 |
---|---|
[SQL] 해커랭크 Occupations 풀이 (0) | 2021.09.22 |
[SQL] LeetCode - 181. Employees Earning More than their Manager (0) | 2021.09.02 |
[SQL] HackerRank - Contest Leaderboard (0) | 2021.09.01 |
[DB] 트랜잭션이란? (0) | 2021.08.24 |