본문 바로가기
DataBase

MySQL GROUP BY에 대한 이해

by 대박플머 2024. 10. 24.

GROUP BY는 MySQL에서 데이터를 그룹화하여 특정 기준에 따라 요약된 결과를 얻을 때 사용됩니다. 대규모 데이터를 처리하거나 집계 연산을 할 때 유용하게 쓰이는 구문이며, 다양한 집계 함수(COUNT, SUM, AVG, MIN, MAX 등)와 함께 자주 사용됩니다. 이번 글에서는 GROUP BY의 기본 개념부터 고급 사용법까지 단계별로 살펴보고, 사용 시 주의할 점과 최적화 방법에 대해 설명합니다.

본격적으로 들아기전에 예시 테이블을 생성 해보도록 하겠습니다.

CREATE TABLE sales (
    id INT AUTO_INCREMENT PRIMARY KEY,
    product_name VARCHAR(255),
    sale_date DATE,
    quantity INT,
    total_price DECIMAL(10, 2)
);

INSERT INTO sales (product_name, sale_date, quantity, total_price) VALUES
('Laptop', '2024-01-10', 3, 3000.00),
('Laptop', '2024-01-15', 2, 2000.00),
('Phone', '2024-01-10', 5, 2500.00),
('Phone', '2024-02-10', 3, 1500.00),
('Tablet', '2024-01-20', 4, 1600.00),
('Tablet', '2024-02-05', 1, 400.00);

1. GROUP BY의 기본 개념

GROUP BY는 쿼리의 결과를 지정한 열(Column)의 값에 따라 그룹화합니다. 예를 들어, 데이터베이스에서 판매 내역을 관리하는 테이블이 있을 때, 각 제품별로 판매된 총 금액을 계산하고 싶다면 GROUP BY를 사용할 수 있습니다.

SELECT product_name, SUM(total_price)
FROM sales
GROUP BY product_name;


위 쿼리는 sales 테이블에서 product_name을 기준으로 그룹을 나누고, 각 그룹에 대해 total_price의 합계를 반환합니다.

2. GROUP BY와 집계 함수

GROUP BY는 일반적으로 집계 함수와 함께 사용됩니다. 집계 함수는 그룹화된 데이터에 대해 연산을 수행하여 요약된 정보를 제공합니다. MySQL에서 자주 사용되는 집계 함수는 다음과 같습니다.

  • COUNT(): 그룹 내 행(row)의 개수를 계산합니다.
  • SUM(): 그룹 내 값들의 합계를 계산합니다.
  • AVG(): 그룹 내 값들의 평균을 계산합니다.
  • MIN(): 그룹 내 최소값을 반환합니다.
  • MAX(): 그룹 내 최대값을 반환합니다.

예시:
GROUP BY는 다양한 집계 함수와 함께 사용됩니다. 예를 들어, SUM() 외에도 COUNT() 함수는 각 그룹의 행 개수를 계산하며, AVG() 함수는 평균 값을 계산합니다.

다음 쿼리는 제품별로 총 판매 수량과 평균 판매 금액을 반환합니다.

SELECT product_name, SUM(quantity) AS total_quantity, AVG(total_price) AS avg_price
FROM sales
GROUP BY product_name;

 

3. HAVING 절과 GROUP BY

GROUP BY를 사용할 때, 결과를 필터링하려면 HAVING 절을 사용할 수 있습니다. HAVING 절은 GROUP BY로 그룹화된 데이터에 대한 조건을 설정하는데, 이는 WHERE 절과 유사하지만 GROUP BY 이후에 집계 함수 결과를 필터링할 수 있다는 점에서 다릅니다.

SELECT product_name, SUM(total_price) AS total_sales
FROM sales
GROUP BY product_name
HAVING SUM(total_price) > 3000;


이 쿼리는 총 판매 금액이 3000을 초과하는 제품만 반환합니다. 결과는 다음과 같습니다.

4. GROUP BY와 정렬

GROUP BY와 함께 ORDER BY를 사용하여 그룹화된 결과를 정렬할 수 있습니다. 일반적으로 ORDER BY는 그룹화된 열이나 집계 함수의 결과를 기준으로 정렬됩니다.
예를 들어, 총 판매 금액에 따라 제품을 내림차순으로 정렬하려면 다음과 같은 쿼리를 사용할 수 있습니다.

SELECT product_name, SUM(total_price) AS total_sales
FROM sales
GROUP BY product_name
ORDER BY total_sales DESC;

 

5. GROUP BY에서 다중 열 그룹화

MySQL에서 GROUP BY는 다중 열을 기준으로 그룹화할 수 있습니다. 예를 들어, 제품명과 판매 날짜를 기준으로 그룹화하여 월별 제품 판매 내역을 요약할 수 있습니다.

SELECT product_name, MONTH(sale_date) AS sale_month, SUM(quantity) AS total_quantity
FROM sales
GROUP BY product_name, sale_month;

 

6. GROUP BY의 성능 최적화

GROUP BY는 데이터베이스 성능에 영향을 미칠 수 있습니다. 특히 대용량 데이터를 다룰 때는 효율적인 쿼리 작성을 통해 성능을 최적화해야 합니다. 이를 위해 몇 가지 팁을 제시합니다.

  • 인덱스 사용: GROUP BY에 사용되는 열에 인덱스를 생성하면 성능이 향상됩니다. 인덱스는 데이터 검색을 빠르게 하여 쿼리 속도를 높여줍니다.
  • CREATE INDEX idx_product_name ON sales(product_name);
  • 임시 테이블 사용: 큰 테이블의 경우 GROUP BY의 중간 결과를 임시 테이블에 저장하면 성능이 개선될 수 있습니다.
CREATE TEMPORARY TABLE temp_sales AS
SELECT product_name, sale_date, quantity, total_price
FROM sales;
  • 적절한 인덱스 설계: 자주 사용하는 열에 대해 복합 인덱스를 생성하여 성능을 향상시킬 수 있습니다.
CREATE INDEX idx_product_sale ON sales(product_name, sale_date);

7. GROUP BY 사용 시 주의사항

GROUP BY를 사용할 때 주의해야 할 몇 가지 사항이 있습니다.

  • SELECT 절에서 비집계 열: MySQL에서 GROUP BY를 사용할 때는 집계되지 않은 열을 SELECT 절에 포함시키면 에러가 발생할 수 있습니다. 모든 비집계 열은 반드시 GROUP BY에 포함되어야 합니다. 그렇지 않으면 의도하지 않은 결과를 초래할 수 있습니다.올바른 사용 예시는 다음과 같습니다.
-- 올바른 예시 
SELECT product_name, sale_date, SUM(quantity) 
FROM sales 
GROUP BY product_name, sale_date;

 

-- 잘못된 예시 
SELECT product_name, sale_date, SUM(quantity) 
FROM sales 
GROUP BY product_name; -- sale_date는 포함되지 않음

 

  • NULL 값 처리: GROUP BYNULL 값을 하나의 그룹으로 간주합니다. 따라서, NULL 값을 포함한 열을 기준으로 그룹화하면 하나의 NULL 그룹이 생성됩니다.

8. 실전 예시: 월별 판매 내역 요약

다음 쿼리는 월별로 제품 판매 내역을 요약하고, 매출 순으로 정렬하는 예시입니다.

SELECT product_name, MONTH(sale_date) AS sale_month, SUM(quantity) AS total_quantity, SUM(total_price) AS total_revenue
FROM sales
GROUP BY product_name, sale_month
ORDER BY total_revenue DESC;

 

9. 결론

이번 글에서는 MySQL에서 GROUP BY의 기본 개념부터 고급 사용법까지 살펴보았습니다. GROUP BY는 데이터를 요약하고 집계하는 데 필수적인 구문으로, 다양한 집계 함수와 함께 강력한 기능을 발휘합니다. 그러나 성능 문제를 방지하려면 적절한 인덱스 설정과 최적화 전략이 필요하며, 사용 시 집계되지 않은 열에 주의해야 합니다.