본문 바로가기

SQL/LeetCode

[SQL] Last Person to Fit in the Bus(LeetCode/Oracle)

안녕하세요!

 

이번 포스팅은 LeetCode에 있는 Last Person to Fit in the Bus 문제를 OracleDB로 풀어보려고 합니다!

 

(모든 문제는 Oracle로 풀이하겠습니다.)

 

1. 문제 링크 : https://leetcode.com/problems/last-person-to-fit-in-the-bus/description/

 

2. 문제

Column name Type
person_id int
person_name varchar
weight int
turn int
[문제] There is a queue of people waiting to board a bus. However, the bus has a weight limit of 1000 kilograms, so there may be some people who cannot board.

Write a solution to find the person_name of the last person that can fit on the bus without exceeding the weight limit. The test cases are generated such that the first person does not exceed the weight limit.

버스의 무게 제한이 1000kg입니다. 몸무게 제한을 초과하지 않고 버스에 탈 수 있는 마지막 사람의 이름을 조회하는 문제입니다.

 

3. 제출 쿼리 및 설명

 

1) SUM(WEIGHT)를 윈도우 함수를 사용해서 누적합한 TOTAL_WEIGHT를 추가적으로 생성합니다.

각 행의 WEIGHT에 누적으로 합산해서 행마다 누적합이 반환됩니다.

SELECT
    TURN, PERSON_ID AS ID, PERSON_NAME AS NAME, WEIGHT, 
    SUM(WEIGHT) OVER(ORDER BY TURN
                    ROWS UNBOUNDED PRECEDING) AS TOTAL_WEIGHT
FROM QUEUE

2) 누적합(TOTAL_WEIGHT)이 1000보다 작거나 같으면 됩니다. TOTAL_WEIGHT를 내림차순 정렬한 순위 리스트 RK를 생성합니다.

SELECT 
    TURN, ID, NAME, WEIGHT, TOTAL_WEIGHT,
    ROW_NUMBER() OVER(ORDER BY TOTAL_WEIGHT DESC) AS RK
FROM (
    SELECT
        TURN, PERSON_ID AS ID, PERSON_NAME AS NAME, WEIGHT, 
        SUM(WEIGHT) OVER(ORDER BY TURN
                        ROWS UNBOUNDED PRECEDING) AS TOTAL_WEIGHT
    FROM QUEUE
)
WHERE TOTAL_WEIGHT <= 1000

최종) RK가 1위인 사람이 마지막에 탄 사람이고, 그 사람의 이름을 조회합니다.

SELECT NAME AS person_name
FROM (
    SELECT 
        TURN, ID, NAME, WEIGHT, TOTAL_WEIGHT,
        ROW_NUMBER() OVER(ORDER BY TOTAL_WEIGHT DESC) AS RK
    FROM (
        SELECT
            TURN, PERSON_ID AS ID, PERSON_NAME AS NAME, WEIGHT, 
            SUM(WEIGHT) OVER(ORDER BY TURN
                            ROWS UNBOUNDED PRECEDING) AS TOTAL_WEIGHT
        FROM QUEUE
    )
    WHERE TOTAL_WEIGHT <= 1000
)
WHERE RK = 1