본문 바로가기

코딩일기

SQL 코드카타 111 - Last Person to Fit in the Bus

https://leetcode.com/problems/last-person-to-fit-in-the-bus/description/

 

Column Name Type
person_id int
person_name varchar
weight int
turn int

 

Queue 테이블:

  • person_id : 테이블의 고유 키
  • person_name : 버스를 기다리는 사람의 이름
  • weight : 사람의 체중(kg)
  • turn : 탑승순서

1000킬로그램의 제한을 초과하지 않고 버스에 탈 수 있는 마지막 사람의 person_name을 찾는 해결책을 작성하세요. 테스트 케이스는 첫 번째 사람이 체중 제한을 초과하지 않는다는 조건으로 생성됩니다.

 

select
    Turn,
    person_name,
    Weight,
    SUM(Weight) OVER (ORDER BY Turn) Total_Weight
from Queue
order by Turn

 

먼저 체중의 누적합을 계산한다. turn을 기준으로 정렬하고 turn을 기준으로 weight의 누적합을 새로운 열에 출력한다.

 

select *
from
(select
    Turn,
    person_name,
    Weight,
    SUM(Weight) OVER (ORDER BY Turn) Total_Weight
from Queue
order by Turn) a
where Total_Weight >= 1000

 

다음으로 누적합이 1000이상이 되는 승객들만 필터링한다.

select person_name 
from
(select
    Turn,
    person_name,
    Weight,
    SUM(Weight) OVER (ORDER BY Turn) Total_Weight
from Queue
order by Turn) a
where Total_Weight >= 1000
order by Total_Weight
limit 1

 

오름차순으로 정렬한 후 가장 위의 값만 출력하도록 한다. 그리고 가장 위에 있는 승객의 이름(= 마지막으로 탑승한 승객)을 출력한다.

다만 해당 방법으로는 테스트를 통과하지 못했다. 반례를 보니 모든 승객들이 탑승할 수 있는 경우에는 값이 출력되지 않기 때문이다.

 

select person_name
from
(select
    Turn,
    person_name,
    Weight,
    SUM(Weight) OVER (ORDER BY Turn) Total_Weight
from Queue
order by Turn) a
where Total_Weight <= 1000
order by Turn DESC
limit 1

 

따라서 조건을 반대로 바꿔주었다. 누적합이 1000을 넘지 않는 승객들만을 필터링한 후(탑승한 승객들만 필터링) 내림차순정렬해서 (나중에 탑승한 순서대로 출력) 가장 위에 있는 승객의 이름만 출력하도록 했다.

 

성공!

 

문제자체는 어렵지 않았지만 부분합을 계산해본 부분은 참고할만했다. 처음 SQL에 입문할때 방법은 배웠었는데 한참동안 사용할 일이 없어서 사용법을 잊고있었다.