오늘 풀어보면서 공부할 문제는 Hackerrank에서 출제한 SQL Project Planning이다. 이 문제를 풀 때 개인적으로 Exists문을 통해서 풀어 냈고, 이 과정에서 배운 것을 공유하고자 한다.
목차
1. 문제 출처 및 소개
2. Exists문을 통한 문제 풀이
3. Lesson Learned
1. 문제 출처 및 소개

- 문제의 출처: URL
- 문제의 요구 조건 정리
- 모든 프로젝트의 시작일과 종료일을 호출하는 것
- 정렬 순서는 프로젝트 기간을 기준으로 오름차순으로 할 것
- 문제의 특이사항 정리
- 모든 Task의 시작일과 종료일은 1일로 제한
- Task의 종료일과 Task의 시작일이 겹치면 그것은 같은 프로젝트
여기서 문제의 핵심은 Task에 부여되어 있는 시작일과 종료일을 어떻게 전처리를 하는가에 있다. 더 자세한 풀이는 아래의 영역을 참고하기를 바란다.
2. Exists문을 통한 문제 풀이
문제 풀이 공략은 바로 연속되는 일자를 어떻게 처리하는가에 있다. 그래서 첫 번째 단계는 시작일과 종료일을 서로 분기 처리하는 것이다. 그 다음에는 프로젝트의 시작일과 종료일은 겹치면 안 되기 때문에 Full Join을 시켜 준 뒤에 고유한 값을 알아내면 될 것이다. 자세한 과정은 아래의 코드 설명을 참고하기를 바란다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
SELECT t1.start_date
, MIN(t2.end_date)
FROM (
SELECT a.start_date
FROM Projects a
WHERE 1 = 1
AND NOT EXISTS (
SELECT a2.end_date
FROM projects a2
WHERE a2.end_date = a.start_date
)
) t1
, (
SELECT b.end_date
FROM Projects b
WHERE 1 = 1
AND NOT EXISTS (
SELECT b2.end_date
FROM projects b2
WHERE b2.start_date = b.end_date
)
) t2
WHERE 1 = 1
AND t1.start_date < t2.end_date
GROUP BY t1.start_date
ORDER BY DATEDIFF(t1.start_date, MIN(t2.end_date)) DESC, t1.start_date ASC;
|
cs |
- 문제 풀이 공략
- Step1. 시작일과 종료일을 서로 다르게 구분한다.
- Subquery에서 이를 수행했고, 시작일과 종료일이 겹치는 기간이 있으면 그것은 Task 단위의 데이터이고 프로젝트 단위가 아니기 때문에 제거해야 한다.
- 그래서 Subquery문 내에서 Exists문을 통해 상호배타적인 시작일과 종료일을 불러왔다.
- Step2. Full Join을 통해 가능한 모든 가능한 경우의 수를 불러온다.
- FULL JOIN을 하는 가장 간단한 방법 중 하나는 단순히 Table을 2개 호출하면 된다.
- 다만, 이 방법은 메모리를 많이 쓰기 때문에 실무용이라기보다는 문제풀이 방법에 가깝다.
- Step3. Where절과 GROUP BY 를 통해 데이터를 전처리한다.
- Full Join을 하게 되면 모든 경우의 수가 나타나기 때문에 정답을 위한 전처리를 해야 한다.
- 첫 번째는 where 절을 통해 시작일 >= 종료일인 에러 케이스는 제거한다.
- 두 번째는 MIN(종료일)일 선택하게 되면, 프로젝트 시작일과 가장 가까운 종료일만 불러오게 된다. 이렇게 하게 되면 문제에서 요구하는 프로젝트의 시작일과 종료일을 찾을 수 있다는 점이다.
- Step4. 문제에서 요구한 정렬 순서를 맞춘다.
- Step1. 시작일과 종료일을 서로 다르게 구분한다.
3. Lesson Learned
이 문제는 개인적으로 많은 주제에 대해서 공부를 할 수 있었다. 그 중에서 다른 문제 풀이에도 활용할 수 있을만한 주제에 대해서 간단히 오답노트를 기록하고 공유하도록 하겠다.
✅ Full Join을 하는 방법
Full Join을 하는 방법은 Join문을 써서 할 수도 있지만, 간단하게 Table 2개를 호출하면 된다. 하지만 이 방법은 위에서도 서술하였듯이 시공간 복잡도가 불필요하게 올라가는 단점이 있다. 따라서 이 방법은 실무나 문제의 성격에 따라 활용을 할 때 단점으로 작용할 수도 있다.
✅ Exists 문을 통한 데이터 제어
사실 이 것은 IN을 통해서 해결할 수도 있었지만, 연습을 한다는 차원에서 Exist문을 활용하였다. 이 함수는 실무에서도 활용도가 높으니 공부해두는 것을 추천한다.
✅ GROUP BY를 통한 데이터 전처리
GROUP BY는 보통 집계를 하기 위해서 쓰는 경우가 많다. 하지만 이 문제를 통해서 불필요한 데이터를 제거하기 위해서 집계함수를 활용할 수도 있다는 스킬을 배웠던 것 같다.
'SQL - Mysql & Oracle > SQL 실전 코딩 테스트' 카테고리의 다른 글
[MySQL] Hackerrank - Challenges 문제 풀이 및 해설 (0) | 2023.11.23 |
---|---|
[MySQL & Oracle]HackerRank - Occupations 해설 및 오답노트 (0) | 2023.09.27 |
[MySQL] HackerRank - The Report 해답 및 오답 노트 (0) | 2023.09.26 |
SQL 코딩 테스트 오답노트 작성 요령(합격률 올리는 꿀팁!) (0) | 2023.09.23 |
데이터 분석가의 코딩테스트 대비 A to Z(feat. 예제, 사이트, 계획) (0) | 2023.09.02 |