새소식

SQL

SQL | MySQL | 그룹에 따른 집계 - GROUP BY, HAVING

  • -

 

 

 

 01. GROUP BY 절

 

  • GROUP BY절은 특정 컬럼을 기준으로 그룹화하여 테이블에 존재하는 행들을 그룹별로 구분해 준다. 
  • 그룹 함수를 쓰되, 어떤 컬럼값을 기준으로 그룹 함수를 적용할지 기술해야 함.
  • GROUP BY Syntax
SELECT column names FROM table_references
[WHERE where_condition ]
[GROUP BY {column name | expr | position}
  [ASC | DESC], ... [WITH ROLLUP]]
[HAVING where_condition]

 

1)  그룹 함수 

 

    그룹 함수는 여러 개의 레코드를 하나의 그룹으로 묶어서 계산을 수행

    

➡️MySQL에서 자주 사용되는 그룹 함수들(NULL값은 집계X)

 

  • COUNT( ) : 그룹의 레코드 수를 반환/ COUNT(*)은 모든 레코드 수 반환, COUNT(column)은 특정 컬럼 값이 NULL이 아닌 레코드 수를 반환
  • SUM( ) : 그룹의 특정 컬럼 값을 합산한 결과를 반환
  • AVG( ) :  그룹의 특정 컬럼 값을 평균값으로 계산한 결과를 반환
  • MAX( ) : 그룹의 특정 컬럼 값 중 최대값을 반환
  • MIN( ) : 그룹의 특정 컬럼 값 중 최소값을 반환

✔️더 많은 그룹함수 ➡️https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html

 

MySQL :: MySQL 8.0 Reference Manual :: 12.20.1 Aggregate Function Descriptions

MySQL 8.0 Reference Manual  /  ...  /  Functions and Operators  /  Aggregate Functions  /  Aggregate Function Descriptions 12.20.1 Aggregate Function Descriptions This section describes aggregate functions that operate on sets of values. They are

dev.mysql.com

 

 

2)  그룹 함수와 GROUP BY 실습

 

  • 예제 테이블
CREATE TABLE group_tb (
    id INT PRIMARY KEY,
    name VARCHAR(50),
    gender ENUM('M', 'F'),
    age INT,
    nationality VARCHAR(50),
    income DECIMAL(10, 2)
);

INSERT INTO group_tb VALUES
    (1, 'Alice', 'F', 25, 'USA', 50000),
    (2, 'Bob', 'M', 30, 'USA', 60000),
    (3, 'Charlie', 'M', 35, 'USA', 70000),
    (4, 'David', 'M', 40, 'USA', 80000),
    (5, 'Emily', 'F', 45, 'USA', 90000),
    (6, 'Frank', 'M', 50, 'USA', 100000),
    (7, 'George', 'M', 55, 'USA', 110000),
    (8, 'Hannah', 'F', 60, 'USA', 120000),
    (9, 'Isaac', 'M', 25, 'Canada', 55000),
    (10, 'Jacob', 'M', 30, 'Canada', 65000),
    (11, 'Kate', 'F', 35, 'Canada', 75000),
    (12, 'Liam', 'M', 40, 'Canada', 85000),
    (13, 'Mia', 'F', 45, 'Canada', 95000),
    (14, 'Nathan', 'M', 50, 'Canada', 105000),
    (15, 'Olivia', 'F', 55, 'Canada', 115000),
    (16, 'Patrick', 'M', 60, 'Canada', 125000),
    (17, 'Quinn', 'F', 25, 'UK', 60000),
    (18, 'Ryan', 'M', 30, 'UK', 70000),
    (19, 'Sophia', 'F', 35, 'UK', 80000),
    (20, 'Thomas', 'M', 40, 'UK', 90000);

 

 

 

✔️ 모든 레코드 수 조회

SELECT COUNT(*) 
FROM group_tb;

 

 

✔️ USA 국적 레코드 수 조회

SELECT COUNT(*) 
FROM group_tb 
WHERE nationality = 'USA';

 

 

✔️ 각 국적별 레코드 수 조회

SELECT nationality, COUNT(*) 
FROM group_tb 
GROUP BY nationality;

 

 

✔️ 국적별 평균 소득 조회

SELECT nationality, AVG(income) 
FROM group_tb 
GROUP BY nationality;

 

 

✔️ 국적별 총소득 조회

SELECT nationality, SUM(income) 
FROM group_tb 
GROUP BY nationality;

 

 

✔️ 나이별 최대 소득 조회

SELECT FLOOR(age/10)*10 AS age_group, 
       MAX(income) 
FROM group_tb 
GROUP BY age_group;

 

 

 

✔️ 나이별 최소 소득 조회

SELECT FLOOR(age/10)*10 AS age_group, 
       MIN(income) 
FROM group_tb 
GROUP BY age_group;

 

 

 

 

 

 

02. WITH ROLLUP

 

 

  • WITH ROLLUP을 사용하여 전체의 집계값을 계산할 수 있다. 
SELECT
  gender, COUNT(*)
FROM group_tb
GROUP BY gender WITH ROLLUP;

 

gender 변수에서 각각 여성과 남성이 몇 명인지 count 해주고 그 집계값의 총계를 계산해 준다.

 

SELECT
  gender, nationality, COUNT(*)
FROM group_tb
GROUP BY gender, nationality WITH ROLLUP;

 

 

 

 

 

03. HAVING 절 - 그룹화된 데이터에 조건을 주어 데이터 추출

 

 

  • HAVING 절은 GROUP BY 절과 함께 사용되며, 그룹화된 결과 집합에 대한 조건을 지정하는 데 사용
  • ✨WHERE 절은 개별 행에 대한 조건을 지정하고, HAVING 절은 그룹화된 결과 집합에 대한 조건 지정

 

 

✔️ 국적, 나이별 총소득 중 총소득이 200,000 이상인 행 추출

-- 모든 총소득
SELECT
  nationality, gender, 
  Sum(income) AS sum_income
FROM group_tb
GROUP BY nationality, gender;

 

 

-- sum_income이 200,000 이상인 행 추출
SELECT
  nationality, gender, 
  Sum(income) AS sum_income
FROM group_tb
GROUP BY nationality, gender
HAVING sum_income >= 200000;

 

 

 

 

 

04. DISTINCT - 중복된 행 제거

 

 

  • DISTINCT는 중복된 값을 제거하고 유일한 값을 반환
  • SELECT 문에서 사용
  • GROUP BY 와 달리 집계함수가 사용되지 않으며, 정렬하지 않아서 더 빠름

 

SELECT nationality FROM group_tb GROUP BY nationality;

 

 

SELECT DISTINCT nationality FROM group_tb;

 

 

GROUP BY는 nationality가 내림차순으로 정렬되어 있지만 DISTINCT를 썼을 경우는 정렬이 되어 있지 않음

 

 

  • 여러 개의 열을 선택하여 DISTINCT를 사용할 수 있음
  • 이 경우 선택된 열의 값이 모두 같은 경우에 중복으로 여겨 제거됨.
SELECT DISTINCT nationality, gender 
FROM group_tb
ORDER BY nationality, gender;

 

 

 

 

 

 

 

 


출처 및 참고 문헌(reference)

 

Contents