백엔드 부트캠프[사전캠프]/문제풀이

[SQL 달리기반 레벨 4] 🛒 단골 고객님 찾기

sintory-04 2025. 1. 31. 21:55

문제 🛒 단골 고객님 찾기

1. 고객별로 주문 건수와 총 주문 금액을 조회하는 SQL 쿼리를 작성해주세요. 

a. 출력 결과에는 고객 이름, 주문 건수, 총 주문 금액이 포함되어야 합니다. 

단, 주문을 한 적이 없는 고객도 결과에 포함되어야 합니다.

b. 기대결과

CustomerName
OrderCount
TotalSpent
Alice
2
450
Bob
2
280
Charlie
1
50
David
1
400

 

2. 나라별로 총 주문 금액이 가장 높은 고객의 이름과 그 고객의 총 주문 금액을 조회하는 SQL 쿼리를 작성해주세요.

a. 기대결과

Country
Top_Customer
Top_Spent
USA
Alice
450
UK
Bob
280
Canada
David
400

1. 알고리즘

1) 고객별로 주문 건수와 총 주문 금액을 조회

- 고객별로 GROUP BY를 해야함. 

- 고객이름, 주문 건수, 총 주문금액 포함. 

- 주문 한적 없는 고객도 결과 포함. > LEFT 조인 해야함.

2) 나라별로 총 주문 금액이 가장 높은 고객의 이름과 그 고객의 총 주문 금액을 조회하는 SQL 쿼리를 작성

- 1단계: 먼저, Total Spent 를 구해준다.

- 2단계: Total Spent를 Rank 하여 준다.

- 3단계: Total Spent가 1등인 것만 구해준 후, 요구사항 값과 똑같이 CustomerName 순으로 정렬한다. 

 

2. SQL 코드

1) 

SELECT c.CustomerName, count(*) OrderCount,SUM(TotalAmount) TotalSpent
FROM Customers c LEFT JOIN Orders o on c.CustomerID = o.CustomerID
GROUP BY 1;

2) 

- 2번은 서브쿼리를 사용했다.

- 팀원들이 말했던 대로 ONLY_FULL_GROUP_BY 때문에 조금 까다로웠다.

- 1단계: 먼저, Total Spent 를 구해준다.

SELECT c.CustomerName, SUM(TotalAmount) TotalSpent
FROM Customers c LEFT JOIN Orders o on c.CustomerID = o.CustomerID
GROUP BY 1

- 2단계: Total Spent를 Rank 하여 준다.

SELECT ct.Country, ct.CustomerName, TotalSpent, rank() over(partition by ct.country order by TotalSpent desc) as rnk
from
(
SELECT c.CustomerName, SUM(TotalAmount) TotalSpent
FROM Customers c LEFT JOIN Orders o on c.CustomerID = o.CustomerID
GROUP BY 1
) a inner join Customers ct on a.CustomerName = ct.CustomerName

- 3단계: Total Spent가 1등인 것만 구해준 후, 요구사항 값과 똑같이 CustomerName 순으로 정렬한다.

SELECT Country, CustomerName, TotalSpent
FROM (
SELECT ct.Country, ct.CustomerName, TotalSpent, rank() over(partition by ct.country order by TotalSpent desc) as rnk
FROM
(
SELECT c.CustomerName, SUM(TotalAmount) TotalSpent
FROM Customers c LEFT JOIN Orders o on c.CustomerID = o.CustomerID
GROUP BY 1
) a inner join Customers ct on a.CustomerName = ct.CustomerName
)b
WHERE rnk = 1
ORDER BY CustomerName