-
<프로그래머스> 입양 시각 구하기(2)코딩테스트/SQL 코딩테스트 2024. 1. 9. 14:47
출처 : https://school.programmers.co.kr/learn/courses/30/lessons/59413
- 문제 요구사항
- ANIMAL_OUTS 테이블에서
- 몇 시에 보호소에서 입양이 가장 활발하게 일어나는지를 알아보고자 함
- 0시부터 23시까지 각 시간대별로 입양이 몇 건 발생했는지 조회
- 결과는 시간대 순으로 정렬
- 위 예시처럼 결과가 출력되어야 함
문제 요구사항대로 0시부터 23시까지 입양 건수를 계산하여야하는데
주어진 테이블에서 쿼리에서 시간으로 GROUP BY 하여 출력해보면 0시부터 6시와 20시부터 23시까지의 데이터는
없는 것을 확인할 수 있다. 따라서 생성해주어야 한다.
생성하는 방법 자체는 위처럼 그냥 0부터 1씩 늘려 SELECT로 순차 조회한 것을
UNION ALL로 쿼리 결과를 합치는 방법으로 해결할 수 있을 것 같았다.
방법 자체는 간단할 것 같았으나. 너무 미련한 방법이 아닌가?
MySQL에는 반복문은 없는 걸까? 하는 생각이 들었다.
그래서 검색을 통해 해당 문제의 솔루션을 찾으니 이미 많은 사람들이 해당 문제를 푸는 방법에 대한 블로그를 남겨놓은 것을 찾을 수 있었다. 문제의 해결 방법은 바로 재귀쿼리(계층형 쿼리)를 이용하는 것이었다.
MySQL과 Oracle에서 문제 해결방법이 달랐기 때문에 해당 내용 부분에 대해서 공부하여 쓴 블로그 링크를 참조하였다.
문제 해결방법 쿼리 자체는 달랐지만 내용 자체는 재귀쿼리를 통해 만든 테이블과
기존 테이블에서 GROUP BY를 통해 데이터를 추출한 테이블을 조인하고 이를 통해 문제를 해결했다는 점이다.
1) MySQL
<SQL : MySQL> RECURSIVE(재귀쿼리) / https://jinhyunbae.tistory.com/107
# 재귀 쿼리를 이용해 0부터 23까지의 데이터 행을 가진 임시테이블 생성 WITH RECURSIVE CTE(HOUR) AS ( SELECT 0 UNION ALL SELECT HOUR+1 FROM CTE WHERE HOUR < 23 ) SELECT C.HOUR, IFNULL(O.COUNT, 0) AS COUNT # NULL처리->0 FROM CTE C LEFT OUTER JOIN (SELECT EXTRACT(HOUR FROM DATETIME) AS HOUR, COUNT(*) COUNT #생성한 임시 테이블에 기존 테이블 조인 FROM ANIMAL_OUTS GROUP BY 1) AS O ON C.HOUR = O.HOUR # 시간을 기준으로 GROUP BY
2) Oracle
오라클에서도 WITH RECURSIVE가 동작하는 것으로 알고 있었는데 아무리 코드를 바꾸어 동작 시켜봐도
구문 에러가 나서 다른 방법을 사용하기로 했다.
<SQL : Oralce> - 계층형 쿼리 LEVEL (with DUAL, CONNECT BY) / https://jinhyunbae.tistory.com/108
SELECT H.HOUR, NVL(O.COUNT, 0) AS COUNT # NULL처리->0 FROM (SELECT LEVEL-1 HOUR FROM DUAL CONNECT BY LEVEL-1 < 24) H # 계층형(재귀)쿼리를 통해 0부터 23까지 행을 가지는 테이블을 서브쿼리로 LEFT OUTER JOIN (SELECT TO_CHAR(DATETIME, 'HH24') AS HOUR, COUNT(*) AS COUNT FROM ANIMAL_OUTS # 테이블에서 시간기준 그룹바이 데이터 조인 GROUP BY TO_CHAR(DATETIME, 'HH24')) O ON H.HOUR = O.HOUR ORDER BY H.HOUR
- References
- https://www.mysqltutorial.org/mysql-basics/mysql-recursive-cte/ <MySQL tutorial>
- https://www.geeksforgeeks.org/display-sequence-of-numbers-in-sql-using-level/ <Display sequence of number>
- https://docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm <Oracle Help center>
'코딩테스트 > SQL 코딩테스트' 카테고리의 다른 글
<프로그래머스> 자동차 대여 기록 별 대여 금액 구하기 (0) 2024.01.10 <프로그래머스> 자동차 대여 기록에서 대여중 / 대여 가능 여부 구분하기 (0) 2024.01.10 <프로그래머스> 조건에 부합하는 중고거래 댓글 조회하기 (1) 2024.01.09 <프로그래머스> 저자 별 카테고리 별 매출액 집계하기 (0) 2023.12.28 <프로그래머스> 주문량이 많은 아이스크림 조회하기 (1) 2023.12.28 - 문제 요구사항