1 .주어진 테이블에는 0시~23시까지 모든 시간대의 행이 존재하지 않는다. 따라서 Dual을 통해 모든 시간대 행을 만들어, ANIMAL_OUTS와 조인해야 한다.
2. 이때, connect by level를 통해 연속된 숫자 조회가 가능하다. 여기서 connect by level 사용법을 간단하게 알아보자.
select level
from dual
connect by level < 10;
위 쿼리를 실행하면, 1부터 9까지 조회되는 것을 확인할 수 있다.
초기 시작값을 10으로 하고 싶다면, level + 10을 해준다.
select level + 10
from dual
connect by level < 10;
값을 2씩 증가하도록 쿼리를 작성할 수 있다.
select level*2
from dual
connect by level < 10;
3. connect by level를 사용해 0시~23시 모든 시간대의 행을 조회할 수 있다. 그 다음, 테이블 A와 입양정보 테이블 B의 hour를 사용해 LEFT JOIN 해준다. 모든 시간대 즉, 입양 기록이 없는 시간대도 테이블에 남아있어야하기 때문이다.
4. JOIN 후 시간대 별로 그룹화를 해주고 값이 존재하는 행을 카운트하면 된다. 값이 존재하는 경우만 카운트하기 위해 COUNT(ANIMAL_ID)를 한다. COUNT(*)를 하면 NULL값까지 집계하기 때문에 오답이다.
SELECT A.HOUR, NVL(ANI_CNT,0) AS COUNT
FROM ( SELECT LEVEL-1 AS HOUR
FROM DUAL
CONNECT BY LEVEL < 25 ) A
LEFT JOIN ( SELECT TO_CHAR(DATETIME,'HH24') AS HOUR
, COUNT(ANIMAL_ID) AS ANI_CNT
FROM ANIMAL_OUTS
GROUP BY TO_CHAR(DATETIME,'HH24')
ORDER BY TO_CHAR(DATETIME,'HH24') ) B
ON A.HOUR = B.HOUR
ORDER BY DECODE(A.HOUR,24,0,A.HOUR);