[SQL Runday] HackerRank - SQL Project Planning

Lana Chung·2022년 4월 16일
0

SQLRunday

목록 보기
10/16
post-thumbnail
post-custom-banner

프로젝트 태스크의 ID, 시작 일자, 종료 일자를 담은 Project라는 테이블이 있다. 시작 일자와 종료 일자는 행마다 1일씩 차이 난다.

  • 태스크의 종료 일자가 연속적consecutive이라면, 같은 프로젝트다.
  • 모두 다른 프로젝트의 총 갯수를 구하라.
  • 프로젝트들의 시작 일자와 종료 일자를 출력하는 쿼리를 작성해라.
  • 소요 기간에 따라 오름차순으로 정렬하라, 동일한 값이 있다면 시작 일자 순으로 정렬

Table


Key points

문제 풀이 순서
1. 프로젝트 시작 일자들을 start_date 칼럼에서 구한다. start_date 데이터 중 end_date 칼럼에 값이 없으면 그들이다.
2. 프로젝트 종료 일자들을 end_date 칼럼에서 구한다. end_date 데이터 중 start_date 칼럼에 값이 없으면 그들이다.
3. 시작 일자만 있는 테이블과, 종료 일자만 있는 테이블 2개를 1:1 대응하여 join한다. (여기서 많은 시간을 소요했다..)
4. 마지막으로 프로젝트 duration 기준으로 정렬하기 위해 duration 변수를 만든다.

Errors

  1. 위의 프로세스에서 각 테이블은 쉽게 구했으나 join하는 방법에 애를 먹었다. 왜냐하면 join할 외래키가 없다면 mysql에서는 join을 바로 할 수 없다고 한다. (찾아봤더니 oracle은 fetch first 1 rows only 뭐 이런걸 써서 하더라.) on 없이 join 할 수는 있지만, 그렇게 하면 1:1 대응은 안되고 1:N으로 늘어난다.
  2. 그래서 외래키를 각 테이블에 만들어주는 방법으로 진행하기로 했다. project_id 라는 index를 만들어 두 테이블을 연결했다.
-- 나는 변수를 3개 썼는데, 더 좋은 방법이 있을 거 같다.
set @project_id = 0;
set @project_idx = 0;
set @duration = 0;
select p.start_date, m.end_date
from (select end_date, @project_id:= @project_id+1 as pro_index 
      from projects
      where end_date not in (select start_date from projects))as m
join (select start_date, @project_idx:= @project_idx+1 as pro_idx 
      from projects 
      where start_date not in (select end_date from projects))as p
on m.pro_index = p.pro_idx
order by @duration:= m.end_date - p.start_date
  1. 마지막에 duration 변수를 어디서 만들어줘야 되나 고심했는데, 그냥 order by 뒤에 넣었더니 해결되었다. 자꾸 python이나 기존 변수 만드는 방식으로 생각하다가 시간이 오래 걸리는거 같다. sql은 sql만의 방식이 있다...
profile
그게 쉬운 일이었다면, 아무런 즐거움도 얻을 수 없었을 것이다.
post-custom-banner

0개의 댓글