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
절에 컬럼을 추가하기