본문 바로가기
데이터베이스/SQL

GROUP BY 절 정리

by 코이킹 2023. 7. 22.
반응형

GROUP BY 절은 SQL을 사용하여 데이터를 그룹화할때 사용한다. 

 

1. 기본적인 사용법

예제 데이터로 주문 테이블이 있다고 하자

 

※ 주문 테이블 
주문번호  고객번호   주문일      주문액  
101      1           2023-07-15  100    
102      2           2023-07-16  150     
103      1           2023-07-15  200     
104      3           2023-07-17  120     
105      3           2023-07-17  100

이 주문 테이블에서  고객 별로 주문액의 합계를 출력하고자 한다면 GROUP BY를 사용해서 요건에 맞는 데이터를 출력 가능하다. 

SELECT 고객번호, SUM(주문액) AS 주문액 합계
FROM 주문테이블
GROUP BY 고객번호;

고객번호  주문액 합계
1           300
2           150
3           220

 

 

2. GROUP BY 사용시 주의할 점

1) GROUP BY를 사용할때는 GROUP BY절 뒤쪽에 기술한 기준이 되는 값(컬럼)과 집계함수의 결과만이 출력이 가능하다. 

 

※ 자주쓰는 집계함수 

COUNT(컬럼) 행의 갯수
SUM(컬럼) 지정한 컬럼 값의 합계 
MAX(컬럼) 지정한 컬럼 값중 최대값
MIN(컬럼) 지정한 컬럼 값중 최소값
AVG(컬럼) 지정한 컬럼 값의 평균

 

또한 기준이 되는 컬럼을 여러개 지정할 수 있다. 고객번호별, 주문일별로 그룹화된 데이터를 출력 하고자한다면 아래와 같은 SQL로 원하는 결과를 얻을 수 있다. 

SELECT 고객번호, 주문일, SUM(주문액) AS 주문액합계
FROM 주문
GROUP BY 고객번호, 주문일
ORDER BY 고객번호, 주문일 desc
;

-- 결과 
고객번호  주문일     주문액합계
1         2023-07-15      300
2         2023-07-16      150
3         2023-07-17      120

 

2) 너무 많은 컬럼으로 그룹화하면 결과 데이터가 복잡해질 수 있음. 

예제 데이터를 아래와 같이 1번고객의 103번 주문의 주문일을 변경한후 위의 SQL을 다시실행해보면 어떻게 될까?

※ 주문 테이블(수정)
주문번호  고객번호   주문일      주문액  
101      1           2023-07-14  100    
102      2           2023-07-16  150     
103      1           2023-07-15  200     
104      3           2023-07-17  120     
105      3           2023-07-17  100

-- 결과 
고객번호  주문일         주문액합계
1        2023-07-15      200
1        2023-07-14      100
2        2023-07-16      150
3        2023-07-17      220

주문일 데이터가 7/15, 7/14로 2개가 되었으니 그룹화되는 데이터도 그만큼 늘어나게된다. 

예제는 간단한 데이터라 알기 쉽지만, 컬럼수가 늘어나면 늘어날 수록 복잡해진다. 

2개컬럼을 지정한 경우 그룹화의 조합은 2개지만 

3개컬럼 지정의 경우 2 * 3 = 6, 4개컬럼을 지정한 경우 2 * 3 *4 = 24개 그룹화 조합이 될수있다. 

 

3) 기준이 되는 컬럼의 값의 형식이 바뀌면 바뀐 형식의 값을 Select에 지정해야함

2023년의 월별 주문액의 합계는 아래와 같은 SQL로 구할수 있지 않을까? 

select order_date, sum(amount) from "order" o 
group by to_char(order_date, 'YYYYMM') ;

-- 결과 
SQL Error [42803]: ERROR: column "o.order_date" 
must appear in the GROUP BY clause or be used in an aggregate function

 하지만 위의 결과를보면 에러가 출력되는 것을 알수 있다. 

에러 내용을 보면 GROUP BY에 지정한 컬럼을 안쓰면 안된다고 화내는 것 같은데 나는 확실히 GROUP BY에 지정한 컬럼을 SELECT에 사용했다. 

 

위의 에러를 해결하기 위해서는 어떻게 해야할까? 

select to_char(order_date, 'YYYYMM'), sum(amount) from "order" o 
group by to_char(order_date, 'YYYYMM') ;

-- 결과 
to_char|sum|
-------+---+
202307 |670|

답은 위와 같이 to_char함수로 인해 변경된 데이터의 형식 채로 Select에 넣어야만 출력이 되는 것이었다. 

 

3. HAVING 절 

GROUP BY로 그룹화된 데이터 중에서 조건부 결과를 출력하기 위해서 사용하는 것이 HAVING절이다.

 

고객번호별, 주문일별로 그룹화된 데이터에서 주문액합계가 200이상인 데이터를 출력하려면 아래와 같은 SQL로 원하는 결과를 얻을 수 있다. 

 

select customer_no , order_date ,sum(amount)  from "order" o 
group by customer_no , order_date 
having sum(amount) >= 200 
order by customer_no, order_date desc 
;

-- 결과
customer_no|order_date|sum|
-----------+----------+---+
          1|2023-07-15|200|
          3|2023-07-17|220|

※ HAVING절은 반드시 GROUP BY 의 바로 뒤에 위치해야하며, 집계함수와 같이 사용해야 한다. 

 

 

 

 

 

 

 

 

 

반응형

'데이터베이스 > SQL' 카테고리의 다른 글

JOIN 정리  (0) 2023.07.22
자주쓰는 WHERE문 정리  (0) 2023.07.16

댓글