SQL에서 GROUP BY를 사용할 때, 집계 함수(다중행 함수)를 사용하지 않은 컬럼은 반드시 GROUP BY 절에 포함해야 한다.
그렇지 않으면 오류가 발생한다.
이 개념을 예제와 함께 쉽게 이해해보자.
다음과 같은 orders 테이블이 있다고 가정하자.
| order_id | customer | product | price |
|---|---|---|---|
| 1 | A | Apple | 100 |
| 2 | A | Banana | 200 |
| 3 | B | Apple | 150 |
| 4 | B | Banana | 250 |
| 5 | B | Apple | 300 |
이제 고객별(customer) 총 주문 금액을 구하는 SQL을 작성해보자.
SELECT customer, SUM(price)
FROM orders
GROUP BY customer;
✅ 정상 실행 결과
| customer | SUM(price) |
|---|---|
| A | 300 |
| B | 700 |
만약 product 컬럼을 추가해서 다음과 같이 조회하려 하면 어떻게 될까?
SELECT customer, product, SUM(price)
FROM orders
GROUP BY customer;
❌ 오류 발생!
ERROR: column "orders.product" must appear in the GROUP BY clause or be used in an aggregate function
GROUP BY customer를 했기 때문에 각 고객별(customer)로 한 줄의 결과만 반환해야 한다. product 컬럼은 그룹화되지 않았으므로, 어떤 값을 출력해야 할지 모호하기 때문이다. 예를 들어, 고객 B의 경우 product 컬럼에는 "Apple"과 "Banana"가 포함되어 있는데, 한 줄로 결과를 만들어야 하므로 어떤 값을 넣어야 할지 알 수 없다.
이 문제를 해결하는 방법은 크게 두 가지가 있다.
GROUP BY 절에 컬럼을 추가모든 product별로 그룹을 만들려면 product 컬럼도 GROUP BY에 포함하면 된다.
SELECT customer, product, SUM(price)
FROM orders
GROUP BY customer, product;
🔹 결과
| customer | product | SUM(price) |
|---|---|---|
| A | Apple | 100 |
| A | Banana | 200 |
| B | Apple | 450 |
| B | Banana | 250 |
이렇게 하면 고객별 + 상품별로 그룹화되어 각 조합의 합계를 볼 수 있다.
만약 특정 값을 하나만 선택하고 싶다면 MIN(), MAX(), STRING_AGG() 같은 집계 함수를 사용할 수 있다.
SELECT customer, MIN(product), SUM(price)
FROM orders
GROUP BY customer;
🔹 결과
| customer | MIN(product) | SUM(price) |
|---|---|---|
| A | Apple | 300 |
| B | Apple | 700 |
이 방법은 단순히 알파벳 기준으로 가장 앞에 오는 제품을 선택하는 방식이다.
특정 기준에 따라 제품을 선택하려면 문자열을 묶어서 출력하는 방법을 사용할 수도 있다.
SELECT customer, STRING_AGG(product, ', '), SUM(price)
FROM orders
GROUP BY customer;
🔹 결과
| customer | STRING_AGG(product, ', ') | SUM(price) |
|---|---|---|
| A | Apple, Banana | 300 |
| B | Apple, Banana, Apple | 700 |
이렇게 하면 각 고객이 주문한 모든 상품을 쉼표로 구분하여 출력할 수 있다.
✔ GROUP BY를 사용하면 그룹 단위로 한 줄씩 결과가 반환된다.
✔ GROUP BY에 포함되지 않은 컬럼은 SELECT에서 단독으로 사용할 수 없다.
✔ 해결 방법은
GROUP BY 절에 컬럼을 추가하기