본문 바로가기

Data Literacy/SQL

Chapter 2. JOIN을 이용한 데이터 조합 - (8) 그룹화 : GROUP BY & HAVING 5 [예제]

PostgreSQL Logo Image

 

이번 아티클에서는, 우리가 꽤 오랫동안 살펴본 GROUP BY와 HAVING을 실제로 사용해 보는 예제를 살펴보도록 하겠습니다. DVDRENTAL 데이터베이스에서 실제로 살펴보고자 하는 데이터를 GROUP BY와 HAVING을 사용해 데이터를 추출해 보도록 하겠습니다. 

 

 

 


 

 

* 매장에서 지금까지 누적된 결제 금액이 가장 많은 고객이 누구인지 확인하려고 한다. 이를 위해 "PAYMENT 테이블에서, CUSTOMER_ID를 기준으로 개별 고객 각각 한 명이 얼마를 결제하였는지 총액을 구하고 고객을 결제 고객이 많은 순으로 정렬하시오."

 

우선 PAYMENT 테이블을 기본 형태로 출력해보면 아래와 같습니다. '결제 각 건별로' 누가 결제했는지, 담당 계산원은 누구인지, 그리고 결제 금액(AMOUNT)이 얼마인지를 보여주고 있습니다. 

 

 

 

이제 이 데이터를 고객(CUMSTOMER_ID) 기준으로 누적 결제 금액(AMOUNT)을 구해야 합니다. GROUP BY는 CUSTOMER_ID를 기준으로 작성해야 하고, 출력 칼럼은 CUSTOMER_ID와 각각의 AMOUNT의 총 합계입니다. 정렬 순서는 AS로 선언한 SUM_AMOUNT의 내림차순으로 진행합니다. 

 

select customer_id,
       sum(amount) as sum_amount
  from payment p
 group by customer_id 
 order by sum_amount desc;

 

 

 

 

 

 


 

 

이번에는 위에서 살펴본 내용에 조건을 살짝 추가해 보겠습니다. 

 

* 매장에서 지금까지 누적된 결제 금액이 가장 많은 고객이 누구인지 확인하려고 한다. 이를 위해 "PAYMENT 테이블에서, CUSTOMER_ID를 기준으로 개별 고객 각각 한 명이 얼마를 결제하였는지 총액을 구하고 고객을 결제 고객이 많은 순으로 정렬하시오. (단, 총 결제액 $180 이상인 고객에 한정한다)"

 

위에서 '조건'이 추가되었습니다. 그렇다면 이는 HAVING을 사용해야 하는 쿼리라는 것을 쉽게 눈치 채셨을 것입니다. 

 

select customer_id
       , sum(amount) as sum_amount
  from payment p 
 group by customer_id 
having sum(amount) >= 180 
 order by sum_amount desc;

 

자, 위와 같이 입력하여 아래와 같은 결과를 출력하였습니다. 

 

 

 

 

여기서 복습을 위한 질문 하나 드리겠습니다. HAVING 절에서 SUM_AMOUNT를 사용하지 않고 집계함수 SUM(AMOUNT)를 굳이 사용한 이유는 무엇일까요? 아래 아티클을 통해 이유를 다시 설명해 보시기 바랍니다. 

 

 

Chapter 2. JOIN을 이용한 데이터 조합 - (8) 그룹화 : GROUP BY & HAVING 3

앞선 아티클에서 HAVING의 개념과 기본적인 작동 원칙에 대해서 살펴보았습니다. 그럼 이제 이 내용을 토대로 실제 쿼리를 작성해서 데이터를 확인해 보도록 하겠습니다. Chapter 2. JOIN을 이용한 데

nozeroslope.tistory.com

 

 

 


 

 

마지막으로, 다소 헷갈릴 수 있는 내용이지만 알아두면 유용한(살짝 직관적으로 이해하기 어려운) 내용을 예제를 통해서 살펴보겠습니다. 

 

* PAYMENT에는 고객ID만 있고, 고객의 개인 정보는 CUSTOMER 테이블에 각각 저장되어 있다. 
* 누적 결제 금액 $200 이상인 고객만 추출하여, 쿠폰을 메일로 보내려고 한다. 두 개의 테이블을 이용해 CUSTOMER_ID / EMAIL / 결제금액 총액 칼럼으로 구성된 테이블을 출력하라.

 

select p.customer_id 
       , c.email 
       , sum(p.amount)        
  from payment p, customer c 
 where p.customer_id = c.customer_id 
 group by p.customer_id, c.email 
having sum(p.amount) >= 200;

 

위의 경우, WHERE이 가정 먼저 연산되는 것을 활용하여 두 개의 테이블 중 동일한 CUSTOMER_ID를 가진 데이터로 조건을 미리 한정하고, PAYMENT의 CUSTOMER_ID와 CUSTOMER의 EMAIL로 GROUP BY를 진행했습니다.