MySQL

GROUP BY 와 group 조건 설정

WoodenStella 2023. 1. 10. 13:40

지난 게시글에선 데이터를 검색법을 학습하고, 이를 통해 효율적으로 데이터를 찾아내는 활용을 학습했다.

이에 이어 이번 시간엔 데이터를 통한 비교, 규모 파악을 위해 GROUP BY라는 명령어를 활용하는 법을 학습하고자 한다.

이에 더해, 테이블 생성 시 조건을 설정하는 것에 대해 추가적으로 알아보겠다.

GROUP BY는 데이터를 유형별로 가져오고 싶을 때 쓰는 명령어로써, 두 가지 명령어로 구성된다고 볼 수 있다.

GROUP BY 	# 어떤 것을 그룹화할지 (데이터의 카테고리, 즉 column 값)
HAVING	 	# 어떤 것을 가져올지 (조건)

GROUP BY와 HAVING이 그것이다.

having의 경우 앞서 사용했던 where 과 비슷한 개념으로 생각할 수 있지만,

where의 경우 'group 밖의 조건'을 설정하고, having의 경우 'group 안의 조건'을 설정한다고 생각하면 되겠다.

기본 사용 형식은 다음과 같다.

select           ---컬럼---
  from          ---테이블---
  where          ---조건---
  group by   ---그루핑 할 컬럼---
  order by       ---컬럼---

다음과 같이 지금까지 나온 함수들을 배열하는 순서는 select - from - where - group by - order by 이다.

 

간단한 예시를 들어보자. 고객 별로 얼마나 주문했는지 여부를 알아보면 다음과 같다.

select custid, sum(saleprice)
  from Orders
  group by custid;

이때 다음과 같이 결과가 나온다. custid를 기준으로 그루핑하고, 그 안에 묶인 salesprice를 합산한 값을 출력한 것이다.

응용해서 다음 예시를 보도록 하자.

만약 salesprice가 8000원 이상인 책 중 2권 이상을 구매한 고객의 수를 출력하고 싶다면,

select custid count(*)
  from Orders
  where salesprice >= 8000
  group by custid
  having count(*) >= 2;

다음과 같이 코드를 입력할 수 있다.

해석하자면,

1. custid와 해당 항목의 카운트(*)를 노출시킨다.

2. 타겟으로 하는 위치는 Orders 테이블.

3. salesprice가 8000 이상인 항목이 대상이다.

4. custid를 기준으로 그루핑한다.

5. count(*)이 2 이상인 항목만 나타낸다.

결과는 다음과 같이 나오는데, 이를 조금 구체적으로 해석해 보면 이렇게 된다.

custid
구매 액수
카운트
조건 충족 여부
1
6000
( 카운트 안 됨)
count값 2, 충족
12000
1
21000
2
2
8000
1
count값 1, 충족 못 함
7000
( 카운트 안 됨)
3
6000
( 카운트 안 됨)
count값 2, 충족
12000
1
13000
2
4
20000
1
count값 2, 충족
13000
2
5
none
( 카운트 안 됨)
count값 0, 충족 못 함

이와 같이 GROUP BY 명령어를 사용, 데이터를 그룹화해 관리할 수 있다.

이때 주의할 점은, SELECT를 통해 지정하는 컬럼은 GROUP BY 이후에 나오는 그룹화된 컬럼이 아닌 이상 집계함수(COUNT, SUM, AVG, MAX, MIN)가 들어간 형태여야 한다.

예를 들자면,

select custid
  from Orders
  group by custid;

 

→ ​가능, 그룹화한 컬럼과 select이후의 컬럼이 같다.

 

select *
  from Orders
  group by custid;

​ → 불가능, 그룹화한 컬럼과 select이후의 컬럼이 다르다.

 

select name
  from Orders
  group by custid;

→ 불가능, 그룹화한 컬럼과 select이후의 컬럼이 다르다.

 

select custid, sum(saleprice)
  from Orders
  group bt custid;

→ 가능, 그룹화한 컬럼과 select이후의 컬럼이 같고, 이외의 것에 집계함수가 붙어 있다.

select custid, sum(saleprice), max(orderdate)
  from Orders
  group by custid;

→ 가능, 그룹화한 컬럼과 select이후의 컬럼이 같고, 이외의 것에 집계함수가 붙어 있다.

이와 같다. 오류를 일으키는 까다로운 요소이므로 알아두는 것이 좋겠다.