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

2020. 4. 25. 21:11Database/practice

문제URL (https://programmers.co.kr/learn/courses/30/lessons/59413)

 

프로그래머스

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

programmers.co.kr

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

 

다음 SQL을 통해서 ANIMAL_OUTS 테이블에 있는 시간대를 확인했다.

 

1
2
3
SELECT HOUR(DATETIME) AS HOUR, COUNT(*) AS COUNT
FROM ANIMAL_OUTS
GROUP BY HOUR
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter

 

출력 결과를 보니 0시부터 23시까지 모든 시간대가 ANIMAL_OUTS 테이블에 있는게 아니었다.

따라서 ANIMAL_OUTS에 없는 시간대에 대해서 만들어주고, 그 시간대에는 입양이 되지 않았기 때문에 COUNT 0을 할당해줘야 한다.

 

 

1. 첫번째 풀이

 

1단계

COLUMN 'HOUR'에 0부터 23까지 값을 할당해준다. 이후에 이 테이블은 'ALL_HOURS'이라고 불린다.

 

1
2
3
4
5
6
7
SELECT 0 AS HOUR
    UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 
    UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 
    UNION SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12
     UNION SELECT 13 UNION SELECT 14 UNION SELECT 15 UNION SELECT 16 
     UNION SELECT 17 UNION SELECT 18 UNION SELECT 19 UNION SELECT 20 
     UNION SELECT 21 UNION SELECT 22 UNION SELECT 23
 
1단계 출력

 

 

2단계

1단계에서 작성한 테이블 ALL_HOURS (QUERY)을 기준으로 LEFT JOIN 명령어 이용하여 ANIMAL_OUTS 테이블을 합친다.

 

1

2
3
4
5
LEFT JOIN(
    SELECT HOUR(DATETIME) AS HOUR, COUNT(*) AS COUNT
    FROM ANIMAL_OUTS
    GROUP BY HOUR) AS ANIMAL_HOURS
ON ALL_HOURS.HOUR = ANIMAL_HOURS.HOU
2단계 출력

 

3단계

IFNULL 함수를 이용하여, COUNT의 값이 NULL일때 0으로 대체해준다.

1
IFNULL(ANIMAL_HOURS.COUNT, 0)

 

모든 단계를 합친 SQL 문은 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SELECT ALL_HOURS.HOUR, IFNULL(ANIMAL_HOURS.COUNT, 0) AS COUNT
FROM (
    SELECT 0 AS HOUR
    UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 
    UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 
    UNION SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12
     UNION SELECT 13 UNION SELECT 14 UNION SELECT 15 UNION SELECT 16 
     UNION SELECT 17 UNION SELECT 18 UNION SELECT 19 UNION SELECT 20 
     UNION SELECT 21 UNION SELECT 22 UNION SELECT 23) AS ALL_HOURS
LEFT JOIN(
    SELECT HOUR(DATETIME) AS HOUR, COUNT(*) AS COUNT
    FROM ANIMAL_OUTS
    GROUP BY HOUR) AS ANIMAL_HOURS
ON ALL_HOURS.HOUR = ANIMAL_HOURS.HOUR
ORDER BY HOUR
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter

 

최종 출력

 

2. 두번째 풀이

SET 명령어를 이용하여 변수 HOUR에 -1을 할당한다.

1
2
SET @HOUR = -1;
SELECT (@HOUR := @HOUR + 1) AS HOUR
 

여기서 테이블 크기만큼 HOUR은 순차적으로 1씩 증가한다.

 

1
@HOUR := @HOUR + 1

 

하지만 WHERE 명령어를 통해 HOUR가 23 미만까지 범위를 지정해주었기 때문에 해당 범위까지 HOUR은 1씩 증가하게된다.

1
WHERE @HOUR < 23

 

두 번째 풀이의 모든 단계를 합친 SQL문은 다음과 같다.

1
2
3
4
5
6
7
8
9
SET @HOUR = -1;
 
SELECT (@HOUR := @HOUR + 1) AS HOUR,
       (SELECT COUNT(*)
       FROM ANIMAL_OUTS
       WHERE HOUR(DATETIME= @HOUR) AS COUNT
FROM ANIMAL_OUTS
WHERE @HOUR < 23
ORDER BY HOUR ASC