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

chaechae·2023년 1월 25일
0

코딩테스트(SQL) 

목록 보기
6/22
post-thumbnail

LV4 저자 별 카테고리 별 매출액 집계하기

문제 )
보호소에서는 몇 시에 입양이 가장 활발하게 일어나는지 알아보려 합니다. 0시부터 23시까지, 각 시간대별로 입양이 몇 건이나 발생했는지 조회하는 SQL문을 작성해주세요. 이때 결과는 시간대 순으로 정렬해야 합니다. (자세한 문제내용과 테이블내용은 프로그래머스에 있습니다.)

-- 몇 시에 입양이 가장 활발하게 일어나는지 시간대별로 

# DATETIME 에서 시간을 추출 , HOUR(), MONTH(), DAY() 등등 다양하다.
#  데이터에 입양이 일어난 로그가 없는 시간대가 있기 때문에 재귀 쿼리라는것을 이용해야한다.

WITH RECURSIVE tb1 AS (
    SELECT 0 AS HOUR
    UNION ALL
    SELECT HOUR+1 FROM tb1 WHERE HOUR < 23)
    
, animal AS (SELECT  HOUR(DATETIME) AS HOUR 
                , COUNT(DISTINCT ANIMAL_ID) AS COUNT
            FROM ANIMAL_OUTS
            GROUP BY HOUR
            ORDER BY HOUR)    

SELECT a.HOUR
    , CASE WHEN b.COUNT IS NULL THEN 0 ELSE COUNT END AS COUNT
FROM tb1 a
    LFET JOIN animal b ON a.HOUR = b.HOUR

TIL

  • 재귀쿼리라는 것을 배웠습니다. Recursive !
  • 문제의 흐름대로 HOUR() 함수를 이용해 DATETIME에서 시간(HOUR)만 추출을 한 뒤, 시간별로 Group by 했지만 데이터에 입양이 일어난 로그가 없는 시간대가 있었습니다. ( 0~6 , 20~23 시간대가 포함되어있지 않았습니다.)
  • 즉, 0시~23시까지 모든 시간대 테이블을 만들어야 했고, 이 떄 이용되는 것이 재귀쿼리 였습니다.

RECURSIVE QUEERY

재귀쿼리의 간단한 예시 입니다! 참고문서를 통해 쿼리 작동원리를 설명하면 다음과 같습니다.

  1. 먼저 앵커 멤버(초기값)와 재귀 멤버를 분리합니다.
  2. 앵커 멤버는 초기 행( SELECT 1)을 형성하므로 첫 번째 반복은 n = 1인 1 + 1 = 2를 생성합니다.
  3. 두 번째 반복은 첫 번째 값(2)의 출력에서 작동하고 n = 2인 2 + 1 = 3을 생성합니다.
  4. 세 번째 연산(n=3) 이전에 종료 조건( n < 3)을 만족하여 쿼리를 멈춥니다.
  5. UNION ALL을 이용해 마지막으로 연산자를 사용하여 모든 결과 집합 1, 2 및 3을 결합합니다.
  6. n 컬럼에 1~3 까지의 값을 갖는 테이블이 완성됩니다.

pyhton의 반복문의 원리와 비슷한것 같습니다. 일단 저는 튜토리얼 예시만 익혀두고 재귀쿼리에 대해 깊게 들어가진 않았는데요. 나중에 공식문서를 찾아서 한번 더 공부 해봐야겠습니다 ㅎ ㅎ

profile
게임 혹은 다양한 컨텐츠가 있는 곳을 좋아합니다. 시리즈를 참고하시면 편하게 글을 보실 수 있습니다🫠

0개의 댓글