1204. Last Person to Fit in the Bus
-- 쿼리 구현 시간 순서
--방법 1 : Sum over 함수
WITH A AS(
SELECT person_name, sum(weight) over (order by turn) as cum_sum
FROM queue
)
SELECT person_name
FROM A
WHERE cum_sum <= 1000
ORDER BY cum_sum DESC LIMIT 1
-- 방법 2-1 : Self join 후 order by limit 1
WITH A AS(
SELECT q1.turn, q1.person_name, sum(q2.weight) AS cum_sum
FROM queue q1
LEFT JOIN queue q2
ON q1.turn >= q2.turn
GROUP BY q1.turn
HAVING sum(q2.weight) <= 1000
ORDER BY q1.turn, q2.turn
)
SELECT person_name
FROM A
ORDER BY cum_sum DESC LIMIT 1
-- 방법 2-2 : Self join 후 where in (max())
WITH A AS(
SELECT q1.turn, q1.person_name, sum(q2.weight) AS cum_sum
FROM queue q1
LEFT JOIN queue q2
ON q1.turn >= q2.turn
GROUP BY q1.turn
HAVING sum(q2.weight) <= 1000
ORDER BY q1.turn, q2.turn
)
SELECT person_name
FROM A
WHERE cum_sum in (
SELECT max(cum_sum)
FROM A
)
-- 방법 3 : 서브쿼리
WITH A AS(
SELECT q1.turn, q1.person_name,
(SELECT sum(q2.weight)
FROM queue q2
WHERE q1.turn >= q2.turn)
AS cum_sum
FROM queue q1
)
SELECT person_name
FROM A
WHERE cum_sum <= 1000
ORDER BY cum_sum DESC LIMIT 1
🔒 구해볼 것 : 몸무게 누적합이 1000 넘기 전의 마지막 사람의 이름
🔑 세부 구현
쿼리테스트 1
📌 테이블 설명
| 이름 | 데이터 타입 | 설명 |
|---|---|---|
| PersonType | nchar(2) | 사람의 주요 유형: SC = 상점 연락처, IN = 개인(소매) 고객, SP = 영업 사원, EM = 직원(비영업), VC = 공급업체 연락처, GC = 일반 연락처 |
| EmailPromotion | int | 0 = 이메일 프로모션을 받지 않음, 1 = 회사에서만 이메일 프로모션을 받기를 원함, 2 = 회사 및 파트너사로부터 이메일 프로모션을 받기를 원함. |
📌 쿼리
SELECT count(*) as customer_count
FROM Person_Person pp
WHERE (pp.EmailPromotion = 1 OR pp.EmailPromotion = 2)
and pp.PersonType = 'IN';
🔒 구해볼 것 : 이메일 프로모션에 동의한 “개인(소매)” 고객의 수
🔑 세부 구현
쿼리테스트2
📌 테이블 설명
📌 쿼리
WITH scpp AS(
SELECT sc.CustomerID , pp.FirstName as first_name, pp.LastName as last_name
FROM Sales_Customer sc
LEFT JOIN Person_Person pp
ON sc.PersonID = pp.BusinessEntityID
), ssohod as(
SELECT ssoh.CustomerID as customer_id , sum(ssod.OrderQty) AS total_quantity
FROM Sales_SalesOrderHeader ssoh
LEFT JOIN Sales_SalesOrderDetail ssod
ON ssoh.SalesOrderID = ssod.SalesOrderID
WHERE ssoh.OrderDate LIKE '2011-10%'
GROUP BY 1
HAVING sum(ssod.OrderQty) >= 70
)
SELECT ssohod.customer_id , scpp.first_name, scpp.last_name, ssohod.total_quantity
FROM ssohod
LEFT JOIN scpp
ON ssohod.Customer_ID = scpp.customerID
ORDER BY 1;
🔒 구해볼 것 : 2011년 10월에 제품 70개 이상 구매한 고객 정보 (고객 ID로 오름차순 정렬)
🔑 세부 구현
-- 쿼리 구현 시간 순서
--방법 1 : Sum over 함수
WITH A AS(
SELECT person_name, sum(weight) over (order by turn) as cum_sum
FROM queue
)
SELECT person_name
FROM A
WHERE cum_sum <= 1000
ORDER BY cum_sum DESC LIMIT 1
-- 방법 2-1 : Self join 후 order by limit 1
WITH A AS(
SELECT q1.turn, q1.person_name, sum(q2.weight) AS cum_sum
FROM queue q1
LEFT JOIN queue q2
ON q1.turn >= q2.turn
GROUP BY q1.turn
HAVING sum(q2.weight) <= 1000
ORDER BY q1.turn, q2.turn
)
SELECT person_name
FROM A
ORDER BY cum_sum DESC LIMIT 1
-- 방법 2-2 : Self join 후 where in (max())
WITH A AS(
SELECT q1.turn, q1.person_name, sum(q2.weight) AS cum_sum
FROM queue q1
LEFT JOIN queue q2
ON q1.turn >= q2.turn
GROUP BY q1.turn
HAVING sum(q2.weight) <= 1000
ORDER BY q1.turn, q2.turn
)
SELECT person_name
FROM A
WHERE cum_sum in (
SELECT max(cum_sum)
FROM A
)
-- 방법 3 : 서브쿼리
WITH A AS(
SELECT q1.turn, q1.person_name,
(SELECT sum(q2.weight)
FROM queue q2
WHERE q1.turn >= q2.turn)
AS cum_sum
FROM queue q1
)
SELECT person_name
FROM A
WHERE cum_sum <= 1000
ORDER BY cum_sum DESC LIMIT 1
😅 내가 쓴 답-- CASE WHEN, LAG 활용 시도했으나 실패 ㅜㅜ
SELECT
CASE WHEN LAG(weight) over(order by weight) is null then weight
ELSE LAG(weight) over(order by weight) + weight
FROM queueWITH scpp AS(
SELECT sc.CustomerID , pp.FirstName as first_name, pp.LastName as last_name
FROM Sales_Customer sc
LEFT JOIN Person_Person pp
ON sc.PersonID = pp.BusinessEntityID
), ssohod as(
SELECT ssoh.CustomerID as customer_id , sum(ssod.OrderQty) AS total_quantity
FROM Sales_SalesOrderHeader ssoh
LEFT JOIN Sales_SalesOrderDetail ssod
ON ssoh.SalesOrderID = ssod.SalesOrderID
WHERE ssoh.OrderDate LIKE '2011-10%'
GROUP BY 1
HAVING sum(ssod.OrderQty) >= 70
)
SELECT ssohod.customer_id , scpp.first_name, scpp.last_name, ssohod.total_quantity
FROM ssohod
LEFT JOIN scpp
ON ssohod.Customer_ID = scpp.customerID
ORDER BY 1; 😅내가 쓴 답-- 정답과 동일