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

[SQL 달리기반] Lv4. 단골 고객님 찾기

s_y_130 2025. 6. 19. 15:32

문제

Orders 테이블:

OrderID
CustomerID
OrderDate
TotalAmount
101
1
2024-01-01
150
102
2
2024-01-03
200
103
1
2024-01-04
300
104
3
2024-01-04
50
105
2
2024-01-05
80
106
4
2024-01-06
400

 

Customers 테이블

CustomerID
CustomerName
Country
1
Alice
USA
2
Bob
UK
3
Charlie
USA
4
David
Canada

 

요구사항

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

  • 출력 결과에는 고객 이름, 주문 건수, 총 주문 금액이 포함되어야 합니다. 단, 주문을 한 적이 없는 고객도 결과에 포함되어야 합니다.
  • 기대결과
CustomerName
OrderCount
TotalSpent
Alice
2
450
Bob
2
280
Charlie
1
50
David
1
400

 

 

 

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

  • 기대결과
Country
Top_Customer
Top_Spent
USA
Alice
450
UK
Bob
280
Canada
David
400

 

 

 

제약사항

  • 두 쿼리 모두 서브쿼리, JOIN, GROUP BY, HAVING 등을 사용해 풀 수 있어야 한다.
  • 주문을 한 적이 없는 고객도 첫 번째 쿼리 결과에 포함되어야 한다.

 

 

문제 풀이

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

  • 출력 결과에는 고객 이름, 주문 건수, 총 주문 금액이 포함되어야 합니다. 단, 주문을 한 적이 없는 고객도 결과에 포함되어야 합니다.
select c.CustomerName, 
	   count(o.OrderID) as OrderCount, 
       coalesce(sum(o.TotalAmount), 0) as TotalSpent
from Customers c
left join Orders o on c.CustomerID =o.CustomerID
group by c.CustomerID

 

 

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

 

나라와 고객 이름 그룹화

select c.Country, c.CustomerName as Top_Customer, sum(o.TotalAmount) as Top_Spent
from Customers c
join Orders o on c.CustomerID=o.CustomerID
group by c.Country, c.CustomerName;

그룹화된 결과에 조건 필터링 => having

 

1. 고객 ID 기준 총 금액

select sum(o2.TotalAmount) as subSum
from Customers c2
join Orders o2 on c2.CustomerID=o2.CustomerID
group by c2.CustomerID;

 

2. 고객 ID 기준 총 금액 결과에서 main query 에서의 국가와 매칭되는 max 값 계산

select max(subSum)
from
(
    select sum(o2.TotalAmount) as subSum
    from Customers c2
    join Orders o2 on c2.CustomerID=o2.CustomerID
    where c.Country=c2.Country
    group by c2.CustomerID
) as sub

 

최종 결과

select c.Country, c.CustomerName as Top_Customer, sum(o.TotalAmount) as Top_Spent
from Customers c
join Orders o on c.CustomerID=o.CustomerID
group by c.Country, c.CustomerName
having sum(o.TotalAmount) = (
	select max(subSum)
	from
	(
		select sum(o2.TotalAmount) as subSum
		from Customers c2
		join Orders o2 on c2.CustomerID=o2.CustomerID
        where c.Country=c2.Country
		group by c2.CustomerID
	) as sub
);