본문 바로가기
문제풀이/SQL(My sql)

[문제풀이] 프로그래머스 - 입양 시각 구하기(2)

by kime2 2024. 6. 28.
출처
 

프로그래머스

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

programmers.co.kr

 

 

문제

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

 

문제에 대한 해석

0시부터 23시까지, 각 시간대별로 입양이 몇 건이나 발생했는지 조회

 

풀이(MYSQL)

-- 오답
SELECT date_format(DATETIME,'%H') as HOUR , count(1) as COUNT
from animal_outs
group by 1
order by 1

 

-- mysql 정답
with recursive hourlist as
(
select
0 as time
union all
select time +1
from hourlist
where time < 23
),
animal as
(
select date_format(DATETIME,'%H') times , ANIMAL_ID
from ANIMAL_OUTS
)
    
select hourlist.time as hour , count(ANIMAL_ID) as count
from animal
right join hourlist
on animal.times = hourlist.time
group by hourlist.time
order by hourlist.time

 

오답 정답
-- ORACLE

with time as (
    SELECT (LEVEL-1) AS num
    FROM DUAL
    CONNECT BY LEVEL <= 24
    ),
animals as (
    select  to_char(DATETIME,'HH24') as time , count(animal_id) as count
    from ANIMAL_OUTS
    group by to_char(DATETIME,'HH24') 
     )
select time.num , nvl(animals.count,0) as count
from time left join animals
on time.num = animals.time
order by time.num

 

 

작동순서

💡SQL 실행 순서는 From -> Where -> Group by -> Having -> Select -> Order by ->결과반환

(my sql)

  1. WITH RECURSIVE 절 : 데이터 0을 time컬럼에 저장하여 hourlist라는 테이블 생성한뒤 hourlist테이블에서 time을 1씩 더하는데 23보다 작을때(22)까지 출력하여 1을 더하고 hourlist테이블과 union all을 하라
  2. WITH 절: ANIMAL_OUTS테이블에서 DATETIME컬럼을 시간형태( times  컬럼)로 출력하고 ANIMAL_ID도 출력하여 animal테이블에 저장
  3. FROM 절: animal테이블과 hourlist를 times 와 time을 기준으로 right조인하라
  4. GROUP BY 절: hourlist의 time데이터를 기준으로 그룹화하여 
  5. SELECT 절: time데이터를 기준으로   ANIMAL_ID수를 집계하라

 

배운점

 

mysql에서 시간추출하기 :   DATE_FORMAT(date, format)

 

date의 컬럼이 datetime의 형태가 아닐경우 : CAST(value AS datatype)

 

계층 쿼리 : with recursive 

서브쿼리에서 스스로를 참조하는 CTE(common table expression)

WITH RECURSIVE cte AS -- 재귀쿼리 생성
(
SELECT -- 최초행 반환(재귀X)
UNION ALL
SELECT -- 반복할 추가 행
FROM cte
WHERE -- 반족조건
)

 

oracle에서 데이터 형식 바꾸기 :To_cart(컬럼, 데이터 형태)

https://kr98gyeongim.tistory.com/100

 

null 값 대체하기 : NVL(데이터, 대체할 값)

 

LEVEL : 숫자형식으로 계층수준(상위-> 하위)을 식별하는데, root일때 1부터 추가되는데 이런 구조는 connect by와 함께 사용 가능

SELECT LEVEL
FROM DUAL
CONNECT BY LEVEL <= 5

1

2

3

4

5