본문 바로가기
Algorithm/프로그래머스

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

by whdgus928 2023. 5. 24.

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

 

프로그래머스

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

programmers.co.kr

문제

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

 

간단해보였지만 빈 시간대에 테이블을 생성하는것에서 애를 먹었다. 두 가지 방법으로 풀이하고 알아보겠습니다.

첫 풀이

1. set을 통해 변수를 선언하고 이용할 수 있다

2. hour라는 변수를 선언해 -1부터 23이 될때까지 1씩 더해가며 시간 테이블을 만들 수 있다

3. 만든 시간 테이블과 서브쿼리로 시간을 추출해 개수를 센다 

set @hour=-1;
select @hour:=@hour+1 as hour,
(select count(ANIMAL_ID) from ANIMAL_outs where hour(DATETIME)=@hour) as count
from ANIMAL_OUTS
where @hour < 23;

set이 무엇인가?

- 어떤 변수에 특정 값을 할당할때 쓰는 명령어

- SET 옆에 변수명과 초기값을 설정한다

- @가 붙은 변수는 프로시저가 종료되어도 유지

 - :=은 비교 연산자 =과 혼동을 피하기 위한의 대입 연산입니다.

 

다른 답안

1. with recursive를 사용한 방법이다

2. with recursive를 사용해 시간 테이블을 만든다

3. 테이블을 time에 모든 시간이 필요하므로 right join 하여 시간별 입양개수를 센다

WITH RECURSIVE TIME AS(
    SELECT 0 as hour
    UNION ALL
    SELECT hour + 1 FROM time
    WHERE HOUR < 23)

SELECT time.hour
     , COUNT(animal_id)
FROM (SELECT *
     , HOUR(datetime) AS hour     
FROM animal_outs) AS outs2
     RIGHT JOIN time ON outs2.hour = time.hour
GROUP BY time.hour
ORDER BY time.hour

WITH RECURSIVE이란?

- 재귀 쿼리를 이용하여 메모리 상에 가상 테이블 생성 가능

WITH RECURSIVE cte (n) AS
(
  SELECT 1
  UNION ALL
  SELECT n + 1 FROM cte WHERE n < 5
)
SELECT * FROM cte;

예시를 보면 recursive 구문을 통해 cte라는 뷰를 생성하고 n이라는 column이 존재한다. SELECT 1 구문을 통해 딱 1이 담긴 initial row set 하나를 생성한다. 이제 아래의 반복문을 실행하면서 나온 결과를 모두 UNION ALL 한다. 반복문의 뜻은 n이 가지고 있는 직전 row set 값이 5보다 작을 때, n+1인 row set을 하나 만든다는 것이다.

 

위 과정을 반복하면 아래와 같은 테이블이 만들어진다

 

배운 점

1. set과 with recursive를 통한 가상테이블을 만드는 방법을 배웠다

2. 복습하면서 몇번 더 사용을 해봐야겠다

반응형

댓글