SQL/문제풀이

[HackerRank] SQL Project Planning 📌

응엉잉 2024. 5. 10. 11:51

https://www.hackerrank.com/challenges/sql-projects/problem?isFullScreen=false

SELECT start_date,
    end_date
FROM 
    (SELECT rule,
        MIN(start_date) AS start_date,
        MAX(end_date) AS end_date,
        MAX(end_date) - MIN(end_date) AS days
    FROM (SELECT start_date,
        end_date,
        start_date - ROW_NUMBER() OVER (ORDER BY start_date) AS rule
    FROM projects) a
    GROUP BY rule) b
ORDER BY days, start_date

 

0. 뭔가 .. start_date에 따라 순위를 매겨보면 일단 뭐라도 할 수 있을것같았다

SELECT start_date,
    ROW_NUMBER() OVER (ORDER BY start_date) AS rnk
FROM projects

여기서 규칙을 발견할 수 있다

동일한 프로젝트(연속된 일자)들은 rnk에서 start date의 일자를 뺀 값이 동일하다

1-1 = 0

...

4-4 = 0

이렇게 차이가 0인 row들끼리 1개의 프로젝트,

11-5 = 6

12-6 = 6

차이가 6인 row들끼리 1개의 프로젝트,

이렇게 묶을 수 있다 !

 

1. 동일한 프로젝트임을 알려줄 수 있는 column을 추가하기 위해, 이 규칙을 rule이라는 이름의 column으로 만들면 다음과 같다.

SELECT start_date,
    end_date,
    start_date - ROW_NUMBER() OVER (ORDER BY start_date) AS rule
FROM projects

 

rule로 GROUP BY를 해주면 start_date의 최솟값과 end_date의 최댓값이 각각 프로젝트의 시작 일자와 종료 일자가 될 것이다!

 

2. rule을 기준으로 GROUP BY를 해줘야 했기 때문에 위의 쿼리를 FROM절 서브쿼리로 뺐다.

SELECT rule,
    MIN(start_date) AS start_date,
    MAX(end_date) AS end_date
FROM (SELECT start_date,
    end_date,
    start_date - ROW_NUMBER() OVER (ORDER BY start_date) AS rule
FROM projects) a
GROUP BY rule

 

3. 문제에서 프로젝트 소요 일수별로 정렬을 원했기 때문에, 프로젝트 소요 일수에 대한 column이 필요했다.

SELECT rule,
    MIN(start_date) AS start_date,
    MAX(end_date) AS end_date,
    MAX(end_date) - MIN(end_date) AS days
FROM (SELECT start_date,
    end_date,
    start_date - ROW_NUMBER() OVER (ORDER BY start_date) AS rule
FROM projects) a
GROUP BY rule

 

4. 3번 쿼리 결과를 서브쿼리로 활용해서 문제에서 원하는 것들만 출력해주고 정렬조건도 적어준다

SELECT start_date,
    end_date
FROM 
    (SELECT rule,
        MIN(start_date) AS start_date,
        MAX(end_date) AS end_date,
        MAX(end_date) - MIN(end_date) AS days
    FROM (SELECT start_date,
        end_date,
        start_date - ROW_NUMBER() OVER (ORDER BY start_date) AS rule
    FROM projects) a
    GROUP BY rule) b
ORDER BY days, start_date

 

뭔가 연속성을 이용해야하는데 접근방식을 모르겠으면 window function (row_number())으로 줄세워보고 규칙 찾는것도 좋은거같다!