[mysql] 입양 시각 구하기(2) with recursive 내가 만든 문제도 있
https://school.programmers.co.kr/learn/courses/30/lessons/59413
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
문제 설명
ANIMAL_OUTS 테이블은 동물 보호소에서 입양 보낸 동물의 정보를 담은 테이블입니다. ANIMAL_OUTS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, NAME, SEX_UPON_OUTCOME는 각각 동물의 아이디, 생물 종, 입양일, 이름, 성별 및 중성화 여부를 나타냅니다.
NAME TYPE NULLABLE
ANIMAL_ID | VARCHAR(N) | FALSE |
ANIMAL_TYPE | VARCHAR(N) | FALSE |
DATETIME | DATETIME | FALSE |
NAME | VARCHAR(N) | TRUE |
SEX_UPON_OUTCOME | VARCHAR(N) | FALSE |
보호소에서는 몇 시에 입양이 가장 활발하게 일어나는지 알아보려 합니다. 0시부터 23시까지, 각 시간대별로 입양이 몇 건이나 발생했는지 조회하는 SQL문을 작성해주세요. 이때 결과는 시간대 순으로 정렬해야 합니다.
예시
SQL문을 실행하면 다음과 같이 나와야 합니다.
HOUR COUNT
0 | 0 |
1 | 0 |
2 | 0 |
3 | 0 |
4 | 0 |
5 | 0 |
6 | 0 |
7 | 3 |
8 | 1 |
9 | 1 |
10 | 2 |
11 | 13 |
12 | 10 |
13 | 14 |
14 | 9 |
15 | 7 |
16 | 10 |
17 | 12 |
18 | 16 |
19 | 2 |
20 | 0 |
21 | 0 |
22 | 0 |
23 | 0 |
with recursive hour as (
select 0 as hour
union all
select hour + 1 as hour
from hour
where hour < 23
)
select hour, count(animal_id) as count
from animal_outs as ao right join hour on hour(ao.datetime) = hour.hour
group by hour
order by hour
처음에는 count가 0인걸 어떻게 구해야하지 고민하다가 하드코딩할까 하다가 말이 안돼서 검색의 도움을 받
with recursive로 데이터를 채워주면 됨
with recursive [테이블명] as (..)
그리고 date_format으로 할려고 했는데 00 , 01 ..23 이런식으로 나오게 됨
hour 함수 활용함
hour 테이블의 모든 값은 있어야하니까 right join으로 묶어줌
데이터 예시
1 | Alice | NULL |
2 | Bob | 1 |
3 | Charlie | 1 |
4 | David | 2 |
5 | Eve | 2 |
6 | Frank | 3 |
요구사항
- EmployeeID = 1 (Alice) 부터 시작해서, 모든 하위 직원들을 계층 구조로 조회하는 쿼리를 작성하세요.
- 결과에 EmployeeID, Name, ManagerID, 그리고 직원의 계층 깊이(Level)를 포함하세요.
- Level은 최상위 직원이 1이고, 그 아래 직원은 2, 3, ... 이렇게 증가합니다.
기대 결과 예시
1 | Alice | NULL | 1 |
2 | Bob | 1 | 2 |
3 | Charlie | 1 | 2 |
4 | David | 2 | 3 |
5 | Eve | 2 | 3 |
6 | Frank | 3 | 3 |
WITH RECURSIVE e_chain AS (
-- 비반복 쿼리: 최상위 직원
SELECT employeeID, name, managerID, 1 AS level
FROM Employees
WHERE managerID IS NULL
UNION ALL
-- 재귀 쿼리: 하위 직원들
SELECT e.employeeID, e.name, e.managerID, ec.level + 1 AS level
FROM Employees e
JOIN e_chain ec ON e.managerID = ec.employeeID
)
SELECT * FROM e_chain
ORDER BY level;
최상위 직원은 안바뀌니깐 비반복적인 쿼리에 적어두고 시작.
그 밑에 직원들은 바뀌니까 반복적인 쿼리에 적어두는거임 ㅇㅇ