로운's 기술노트

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

내배캠_데이터분석가_'24.04~08/SQL

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

로운's 2024. 4. 29. 23:09

 

처음엔 단순하게 case when문으로 도전했다가 처참하게 실패하고

이전에 배웠던 *Union all을 이용해 보기로 했다.       * [프로그래머스] 오프라인/온라인 판매 데이터 통합하기 (UNION) (tistory.com)

 

이제 새로 생성한 시간과 ANIMAL_OUTS을 Join하면 어렵지 않게 해결할 수 있..

을 줄 알았는데, 역시 프로그래머스. 호락호락하지 않다.

 

이제 null을 0으로 표현해야 한다.

서치를 해보니 COALESCE 라는 아주 적합한 함수가 있다.

아래 세팅해 놓은 값들 중 null이 있다면 다음 값을 반환해 주는 간단한 형태이다.

SELECT COALESCE(값1, 값2, ...값N);

 

생각해 보니 Union all은 이전에 배웠던 *재귀쿼리(WITH RECURSIVE)로 좀 더 간단하게 해결할 수 있지 않을까?

* [문법] WITH, WITH RECURSIVE 구문 (tistory.com)

 

 

< 풀이1 (Union all) >

select a.Hour, COALESCE(b.cnt,0) as COUNT
from 
    ( SELECT 0 as Hour
         union all SELECT 1
         union all SELECT 2
         union all SELECT 3
         union all SELECT 4
         union all SELECT 5
         union all SELECT 6
         union all SELECT 7
         union all SELECT 8
         union all SELECT 9
         union all SELECT 10
         union all SELECT 11
         union all SELECT 12
         union all SELECT 13
         union all SELECT 14
         union all SELECT 15
         union all SELECT 16
         union all SELECT 17
         union all SELECT 18
         union all SELECT 19
         union all SELECT 20
         union all SELECT 21
         union all SELECT 22
         union all SELECT 23) a
left join         
(select 
date_format(DATETIME, '%H') date_hour,
count(date_format(DATETIME, '%H')) cnt
from ANIMAL_OUTS 
group by date_format(DATETIME, '%H')
) b
on a.Hour = b.date_hour

 

< 풀이2 (재귀쿼리) > 

WITH RECURSIVE a as 
(
    select 0 as num     # 초기값 설정
    union all
    select num+1        # 재귀식 설정
    from a
    where num < 23      # 정지 조건 (23시까지 표현)
)

select a.num as HOUR, COALESCE(b.cnt,0) as COUNT
from a left join 
(
select date_format(DATETIME, '%H') date_hour,
        count(date_format(DATETIME, '%H')) cnt
from ANIMAL_OUTS 
group by date_format(DATETIME, '%H')
) b
on a.num = b.date_hour
GROUP BY a.NUM
ORDER BY a.NUM

 

< 누군가의 또 다른 풀이 (재귀쿼리) >

SET @HOUR := -1;		# @HOUR 변수를 -1로 초기화
SELECT @HOUR := @HOUR + 1 AS HOUR,		# @HOUR 변수를 1씩 증가시키면서, 각 시간대별로 ANIMAL_OUTS 에서 동물의 수를 COUNT
(SELECT count(*) count FROM ANIMAL_OUTS WHERE @HOUR = HOUR (DATETIME)) AS COUNT
FROM ANIMAL_OUTS
WHERE  @HOUR < 23;		# @HOUR 변수가 23보다 작은 동안에만 실행

* MySQL :: MySQL 8.0 레퍼런스 매뉴얼 :: 11.4 사용자 정의 변수

 

"SET @변수 := 값" 구문은 MySQL에서 변수를 초기화하거나 값을 할당하는 데 사용된다.
"@"은 변수를 나타내고, ":="은 변수에 값을 할당하는 데 사용되는 할당 연산자이다.

 

마지막 풀이도 분명 같은 재귀쿼리인데 많이 다르다..

역시 세상은 넓다.

더 정진하자..!

 

 

 

Comments