[HackerRank] SQL Project Planning mysql 문제 풀이
by darami[HackerRank] SQL Project Planning
SQL Project Planning | HackerRank
Write a query to output the start and end dates of projects listed by the number of days it took to complete the project in ascending order.
www.hackerrank.com
다양한 풀이 방법을 적용해보았다. Self join, Lead 함수 등등
결국 오롯이 혼자만의 힘으로 풀지는 못하고 다른 사람들의 답안을 참고하면서 풀었다. 온전히 내것으로 만들면 되는것!
아무래도 연속되는 프로젝트, 날짜에 집중하다 보니 순위 정하기 함수를 쓸 생각을 못했다.
다양한 풀이 방법 중에 알아 두면 좋은 것 (이번 기회에 다시 복습)
#### 순위 정하기 함수
- ROW_NUMBER(), RANK(), DENSE_RANK()
- 셋 다 () 안에 아무런 인자도 들어가지 않음.
ROW_NUMBER: 어떻게든 순위 정해줌, 중복 순위 X / EX) 1>2>3>4
RANK(): 중복 순위 O/ EX) 1>1>3>4>4>
DENSE_RANK(): 중복 순위 O, 빠지는 숫자 없음 / EX) 1>1>2>3>3>3
이중에서 어떻게든 순위를 정하고 중복 순위 없는 ROW_NUMBER를 정해주면
SELECT Start_Date , ROW_NUMBER() OVER(ORDER BY Start_Date) as rnk FROM Projects
이런식으로 나온다. (Start date 중에 빠른 순으로 순위)
코드를 쳐 보면서 내가 이해한 풀이 방법 대로 서술하도록 하겠다.
10월 1일 부터 시작하기에 연속적으로 시작과 끝이 이어진다면 5일 : 5등이 와야하겠지만 그렇지 않다.
그 뜻은 11-5=6, 그 동안의 텀이 있었다는 것! 4일로 부터 6일이 흐른뒤에 11일에 다시 프로젝트를 시작했다.
연속적으로 이어지는 12일도 순위 6을 빼면 5일로 같은 프로젝트임을 알 수 있다. 이 논리를 이용하겠다.

앞의 논리를 이용하면 다음과 같은 결과를 얻을 수 있다.
이렇게 rnk (마지막 컬럼)이 같은 행은 동일한 프로젝트겠거니 라고 유추할 수 있다.
(왜냐면 연속적으로 이어지고 있으니까) 그리고 이렇게 서브 쿼리로 쓸 항목을 따로 떼어낸 것도 이것을 실제로
확인하고 이해하기 위해서다.
SELECT Start_Date , End_Date , Start_Date - ROW_NUMBER() OVER(ORDER BY Start_Date) as rnk FROM Projects

따라서 이제 같은 프로젝트인 것끼리 (rnk) 해주고 그 그룹에서 최소의 start_date와 end_date를 입력해주면
프로젝트의 시작 날짜와 끝나는 날짜를 알 수 있을 것이다.
그리고 적힌 대로 정렬해주면 완성!
SELECT MIN(Start_Date), MAX(End_Date) FROM ( SELECT Start_Date, End_Date, Start_Date - ROW_NUMBER() OVER(ORDER BY Start_Date) as rnk FROM Projects )l GROUP BY rnk ORDER BY DATEDIFF(MAX(End_Date),MIN(Start_Date)), MIN(Start_Date);
그런데 정렬할 때 DATEDIFF(MAX(End_Date),MIN(Start_Date)) 이 자리에 COUNT(*)를 쓴 사람도 있었다.
Group by 했을 때의 행을 세어줘서 가능한것인가? 라는 생각이 들었다.
*다른 풀이
SELECT Start_Date, MIN(End_Date) FROM (SELECT Start_Date FROM Projects WHERE Start_Date NOT IN (SELECT End_Date FROM Projects)) a, (SELECT End_Date FROM Projects WHERE End_Date NOT IN (SELECT Start_Date FROM Projects)) b WHERE Start_Date < End_Date GROUP BY Start_Date ORDER BY DATEDIFF(MIN(End_Date), Start_Date), Start_Date
블로그의 정보
다람
darami