예제(leetcode 1204. Last Person to Fit in the Bus)
버스를 기다리는 승객에 대한 데이터가 아래와 같이 존재한다고 하자. 여기서 weight는 각 승객의 몸무게, turn은 탑승 순서를 의미한다. 버스의 수송 무게 한도가 1000이라고 할 때, 버스에 탑승할 수 있는 마지막 승객은 누구일까?
person_id | person_name | weight | turn |
---|---|---|---|
5 | Alice | 250 | 1 |
4 | Bob | 175 | 5 |
3 | Alex | 350 | 2 |
6 | John Cena | 400 | 3 |
1 | Winston | 500 | 6 |
2 | Marie | 200 | 4 |
착안 사항: turn을 기준으로 몸무게의 누적합을 구한 후 누적합이 1000을 초과하기 전의 승객을 추출한다.
Window 함수 이용방법
WITH CUM AS ( SELECT * , SUM(weight) OVER (ORDER BY TURN) cum_sum FROM queue ) SELECT person_name FROM CUM WHERE cum_sum <= 1000 ORDER BY cum_sum DESC LIMIT 1
비등가 JOIN을 이용하는 방법
SELECT q1.turn, sum(q2.weight) FROM Queue q1 JOIN Queue q2 ON q1.turn >= q2.turn GROUP BY q1.turn HAVING SUM(q2.weight) <= 1000 ORDER BY SUM(q2.weight) DESC LIMIT 1
실행 결과
누적합을 하게 되면 아래와 같은 테이블이 생성되고
person_id | person_name | weight | turn | cum_sum |
---|---|---|---|---|
5 | Alice | 250 | 1 | 250 |
3 | Alex | 350 | 2 | 600 |
6 | John Cena | 400 | 3 | 1000 |
2 | Marie | 200 | 4 | 1200 |
4 | Bob | 175 | 5 | 1375 |
1 | Winston | 500 | 6 | 1875 |
cum_sum이 1000 이하인 마지막 승객명은 아래와 같이 조회된다.
person_id | person_name | weight | turn | cum_sum |
---|---|---|---|---|
5 | Alice | 250 | 1 | 250 |