# Coding/SQL

MySQL 기본 문법 - 정렬 및 그룹화

hxodoo.cookie 2024. 7. 17. 21:47

이 글에서는 MySQL에서 데이터를 정렬하고 그룹화하는 방법을 다루고, 효율적인 쿼리를 작성하는 방법을 알아보겠습니다.
 
 
 
 

MySQL 정렬 및 그룹화

 
 
 
 
 

MySQL 데이터 정렬의 중요성

 
데이터 정렬은 프로그램에서 사용자에게 제공되는 정보를 조직화하고 표시하는 데 중요한 역할을 합니다. 예를 들어, 소셜 미디어 애플리케이션에서 사용자의 피드를 시간순으로 정렬하거나 전자상거래 웹 사이트에서 제품을 가격순으로 정렬하는 것과 같은 경우가 있습니다. 이러한 정렬된 데이터는 사용자가 원하는 정보를 쉽게 찾을 수 있도록 도와줍니다.
 
정렬되지 않은 데이터의 경우 처리하는 데 시간이 오래 걸리고 성능을 저하시킬 수 있습니다. 대량의 데이터가 있는 테이블에서 정렬되지 않은 쿼리를 실행하는 것은 데이터베이스 서버에 부하를 일으키고 조회까지 시간이 오래 걸리는 반면에 데이터가 정렬되어 있다면 필요한 정보를 더 빠르게 검색할 수 있습니다.
 
 
 

[검색 및 필터링 시 정렬의 효율성]

데이터가 정렬되어 있다면 검색 및 필터링 작업이 더욱 효율적으로 수행됩니다. 예를 들어, 사용자가 특정 기준에 따라 정렬된 데이터에서 원하는 항목을 찾으려고 할 때 정렬된 데이터를 사용하면 더 빠르게 원하는 결과를 얻을 수 있습니다. 또한 정렬된 데이터를 사용하면 데이터베이스가 인덱스를 효과적으로 활용하여 검색 속도를 높일 수 있습니다.

 
 
 
 


ORDER BY 절

 
데이터를 정렬하기 위해 가장 일반적으로 사용되는 방법은 ORDER BY 절을 사용하는 것입니다. ORDER BY 절은 SELECT 문과 함께 사용되며, 정렬하고자 하는 열의 이름을 지정합니다. ORDER BY 절은 기본적으로 오름차순(ASC)으로 정렬되지만, DESC 키워드를 추가하여 내림차순으로 정렬할 수도 있습니다.
 
 

-- 예시 테이블 생성
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100),
    age INT
);

-- 예시 데이터 삽입
INSERT INTO users (name, age) VALUES
('Alice', 30),
('Bob', 25),
('Charlie', 35),
('David', 28);

-- 나이를 오름차순으로 정렬하여 데이터 조회
SELECT * FROM users ORDER BY age ASC;

 
 
 
위의 코드에서 사용된 ORDER BY 절은 'age' 열을 기준으로 오름차순으로 데이터를 정렬합니다. 결과는 다음과 같이 출력됩니다.
 
 

[RESULT]

| id |  name   | age |
|----|---------|-----|
|  2 | Bob     |  25 |
|  4 | David   |  28 |
|  1 | Alice   |  30 |
|  3 | Charlie |  35 |

 
 
 
 


 정렬 옵션 설정

정렬 옵션은 ASC(오름차순 정렬)과 DESC(내림차순 정렬)이 있습니다. 정렬 옵션을 생략할 경우 기본적으로 ASC가 적용됩니다.
 
 

데이터 타입별 기본 정렬 (asc) 순서

- 문자 : 영어는 알파벳(A~Z) 순 정렬, 한글은 가나다 순 정렬
- 숫자 : 값이 더 작은 수부터 큰 수로 정렬
- 날짜 : 예전 날짜부터 최근 날짜로 정렬

 
 
 
 


다중 열 정렬

MySQL에서는 단일 열을 기준으로 데이터를 정렬하는 것 외에도 다중 열에 대한 정렬도 지원합니다. 이는 ORDER BY 절에 여러 열을 지정하여 데이터를 첫 번째 열로 정렬한 다음, 동일한 값이 있는 경우 두 번째 열로 정렬하는 것을 의미합니다. 이를 통해 더 정확한 정렬을 수행할 수 있습니다.
 
 

-- 나이를 오름차순으로 정렬하고, 나이가 동일한 경우 이름을 오름차순으로 정렬하여 데이터 조회
SELECT * FROM users ORDER BY age ASC, name ASC;

 
 
 
위의 코드에서는 나이를 먼저 오름차순으로 정렬하고, 그다음에 이름을 오름차순으로 정렬합니다. 결과는 다음과 같이 출력됩니다.
 
 

[RESULT]

| id |  name   | age |
|----|---------|-----|
|  2 | Bob     |  25 |
|  4 | David   |  28 |
|  1 | Alice   |  30 |
|  3 | Charlie |  35 |

 
 
 
이처럼 MySQL에서는 ORDER BY 절을 사용하여 데이터를 원하는 방식으로 정렬할 수 있습니다.
 
 
 


 WHERE 절 정렬과 함께 사용하기

WHERE 절 뒤에 ORDER BY절을 붙여 함께 사용할 수 있습니다. 이 경우 WHERE 절 조건식에 따라 데이터를 필터링한 후 정렬을 수행합니다.
 
 

-- 전제 데이터 중 name에 문자 'a'를 포함하고 있는 데이터 조회
-- 조회된 데이터를 나이를 기준으로 내림차순으로 정렬하고, 나이가 동일한 경우 이름을 오름차순으로 정렬하여 데이터 조회
SELECT * FROM users 
WHERE name LIKE '%a%'
ORDER BY age DESC, name ASC;

 
 
 
users 테이블에서 name의 값이 "a"를 포함하는 데이터들을 age를 기준으로 내림차순으로, 동일한 경우 name을 기준으로 오름차순 정렬한 결과는 아래와 같습니다.
 
 

[RESULT]

| id |  name   | age |
|----|---------|-----|
|  3 | Charlie |  35 |
|  4 | David   |  28 |

 
 
 
 


LIMIT 절

MySQL의 LIMIT 절은 쿼리 결과에서 반환되는 행 수를 제한하는 데 사용됩니다. 이는 특히 대량의 데이터를 다룰 때 유용하며, 페이징 처리와 같은 작업에서 자주 사용됩니다.
 
LIMIT 절은 SELECT 문과 함께 사용되며, 반환할 행 수를 지정할 수 있습니다. 또한, 오프셋 값을 지정하여 특정 위치에서부터 행을 반환할 수 있습니다.
 
 
 

-- 예시 테이블 생성
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100),
    age INT
);

-- 예시 데이터 삽입
INSERT INTO users (name, age) VALUES
('Alice', 30),
('Bob', 25),
('Charlie', 35),
('David', 28);

-- 첫 번째 행만 반환
SELECT * FROM users LIMIT 1;

 
 
 
다음 예제는 'users' 테이블에서 첫 번째 행만 반환합니다.
 
 

[RESULT]

| id |  name | age |
|----|-------|-----|
|  1 | Alice |  30 |

 
 
 
 


LIMIT 절 오프셋과 함께 사용하기

LIMIT 절은 오프셋 값을 함께 사용하여 특정 위치에서부터 행을 반환할 수 있습니다. 
 
 

-- 두 번째 행부터 두 개의 행 반환
SELECT * FROM users LIMIT 1, 2;

 
 
 
이 예제에서는 첫 번째 행을 건너뛰고 그 다음 두 개의 행을 반환합니다. 여기서 LIMIT 1, 2는 "첫 번째 행(0번째 행)을 건너뛰고 두 번째 행부터 시작하여 두 개의 행을 반환하라"는 의미입니다.
 
 

[RESULT]

| id |   name  | age |
|----|---------|-----|
|  2 | Bob     |  25 |
|  3 | Charlie |  35 |

 
 
 
 


LIMIT 절  정렬과 함께 사용하기

 

LIMIT 절은 ORDER BY 절과 함께 사용되어 정렬된 결과에서 특정 수의 행을 반환하는 데 유용합니다. 예를 들어, 나이를 기준으로 오름차순 정렬한 후 처음 두 명의 사용자를 반환하려면 다음과 같이 작성할 수 있습니다.
 
 

-- 나이를 기준으로 오름차순 정렬하고 처음 두 명의 사용자 반환
SELECT * FROM users ORDER BY age ASC LIMIT 2;

 
 
 

[RESULT]

| id |  name | age |
|----|-------|-----|
|  2 | Bob   |  25 |
|  4 | David |  28 |

 
 
 
 


LIMIT 절을 사용한 페이징 처리

LIMIT 절은 페이징 처리에 매우 유용합니다. 페이징 처리는 큰 결과 집합을 여러 페이지로 나누어 각 페이지에서 일부 데이터만 표시하는 방법입니다.
 
예를 들어, 한 페이지에 세 명의 사용자만 표시하려면 다음과 같이 작성할 수 있습니다.
 
 

-- 첫 번째 페이지 (1페이지당 3명씩 표시)
SELECT * FROM users LIMIT 0, 3;

-- 두 번째 페이지
SELECT * FROM users LIMIT 3, 3;

 
 
 
첫 번째 쿼리의 결과는 다음과 같습니다.
 
 

[RESULT]

| id |   name  | age |
|----|---------|-----|
|  1 |  Alice  |  30 |
|  2 |  Bob    |  25 |
|  3 | Charlie |  35 |

 
 
 
두 번째 쿼리의 결과는 다음과 같습니다.
 
 

[RESULT]

| id |  name | age |
|----|-------|-----|
|  4 | David |  28 |

 
 
 
:: 이 예제에서는 첫 번째 쿼리가 처음 세 명의 사용자를 반환하고, 두 번째 쿼리가 네 번째 사용자부터 세 명의 사용자를 반환합니다. 이러한 방식으로 LIMIT 절을 사용하여 쉽게 페이징 처리를 구현할 수 있습니다.
 
 
 
 


MySQL 데이터 그룹화

 
MySQL에서 데이터를 그룹화하는 것은 데이터베이스 관리와 분석에서 매우 중요한 역할을 합니다. 그룹화는 데이터를 특정 기준에 따라 묶어 요약 정보를 제공하며, 이를 통해 데이터의 패턴을 쉽게 파악할 수 있습니다. MySQL에서 GROUP BY 절을 사용하여 데이터를 그룹화하는 방법과 그 필요성에 대해 자세히 살펴보겠습니다.
 
 
 

데이터 그룹화의 필요성

 

1. 데이터 요약과 집계

데이터 그룹화의 주요 목적 중 하나는 데이터를 요약하고 집계하는 것입니다. 예를 들어, 대규모 판매 데이터를 분석할 때 각 제품의 총 판매량을 알고 싶다면 GROUP BY 절을 사용하여 제품별로 데이터를 그룹화하고 SUM() 함수 등을 사용하여 각 그룹의 총 판매량을 계산할 수 있습니다. 이렇게 하면 각 제품의 성과를 한눈에 파악할 수 있습니다.
 
 
 

-- 예시: 제품별 총 판매량 계산
SELECT product_id, SUM(sales) AS total_sales
FROM sales_data
GROUP BY product_id;

 
 
위의 예제는 'sales_data' 테이블에서 'product_id' 열을 기준으로 데이터를 그룹화하고, 각 제품의 총 판매량을 계산합니다. 
 
 
 

2. 데이터 분석

그룹화된 데이터를 사용하면 다양한 측면에서 데이터를 분석할 수 있습니다. 예를 들어, 특정 기간 동안의 매출 추이를 분석하거나, 특정 고객 세그먼트의 구매 패턴을 파악할 수 있습니다. 
 
 
 

-- 예시: 월별 총 매출 계산
SELECT YEAR(order_date) AS year, MONTH(order_date) AS month, SUM(total_amount) AS monthly_sales
FROM orders
GROUP BY YEAR(order_date), MONTH(order_date);

 
 
위의 예제는 'orders' 테이블에서 주문 날짜를 기준으로 연도와 월별로 데이터를 그룹화하고, 각 월의 총 매출을 계산합니다. 
 
 
 

3. 데이터 패턴과 트렌드 파악

그룹화는 데이터 내에서 패턴과 트렌드를 파악하는 데 도움이 됩니다. 예를 들어, 고객의 연령대별 구매 행동을 분석하거나 지역별 판매 성과를 비교할 수 있습니다. 
 
 
 

-- 예시: 연령대별 평균 구매 금액 계산
SELECT age_group, AVG(purchase_amount) AS avg_purchase
FROM customers
GROUP BY age_group;

 
 
위의 예제는 'customers' 테이블에서 연령대별로 데이터를 그룹화하고, 각 연령대의 평균 구매 금액을 계산합니다. 이를 통해 특정 연령대의 구매 성향을 파악할 수 있습니다.
 
 
 
 


MySQL에서 데이터 그룹화하기

MySQL에서는 GROUP BY 절을 사용하여 데이터를 그룹화할 수 있으며, 집계 함수와 함께 사용하여 다양한 형태의 데이터를 분석할 수 있습니다.

 

기본적인 그룹화

 
MySQL에서 가장 기본적인 그룹화는 특정 열을 기준으로 데이터를 묶는 것입니다. 예를 들어, 'sales' 테이블에서 각 제품의 총 판매량을 계산하는 경우를 생각해 봅시다.
 
 
 

-- 예시: 제품별 총 판매량 계산
CREATE TABLE sales (
    product_id INT,
    sale_amount DECIMAL(10, 2)
);

INSERT INTO sales (product_id, sale_amount) VALUES
(1, 100.50),
(2, 200.75),
(1, 150.00),
(3, 300.00),
(2, 50.25);

SELECT product_id, SUM(sale_amount) AS total_sales
FROM sales
GROUP BY product_id;

 
 
위의 쿼리는 'sales' 테이블에서 'product_id'를 기준으로 데이터를 그룹화하고, 각 제품의 총 판매량을 계산합니다. 
 
 

[RESULT]

| product_id | total_sales |
|------------|-------------|
|     1      |    250.50   |
|     2      |    251.00   |
|     3      |    300.00   |

 
 
 
 

다중 열을 사용한 그룹화

 
여러 열을 기준으로 데이터를 그룹화할 수 있습니다. 예를 들어, 'orders' 테이블에서 각 고객의 월별 총 주문 금액을 계산하는 경우를 생각해 봅시다.
 
 
 

-- 예시: 고객별 월별 총 주문 금액 계산
CREATE TABLE orders (
    customer_id INT,
    order_date DATE,
    order_amount DECIMAL(10, 2)
);

INSERT INTO orders (customer_id, order_date, order_amount) VALUES
(1, '2023-01-15', 150.00),
(2, '2023-01-20', 200.00),
(1, '2023-02-10', 100.00),
(3, '2023-02-15', 250.00),
(2, '2023-02-20', 300.00);

SELECT customer_id, MONTH(order_date) AS order_month, SUM(order_amount) AS monthly_sales
FROM orders
GROUP BY customer_id, order_month;

 
 
위의 쿼리는 'orders' 테이블에서 'customer_id'와 주문 월을 기준으로 데이터를 그룹화하고, 각 고객의 월별 총 주문 금액을 계산합니다.
 
 

[RESULT]

| customer_id | order_month | monthly_sales |
|-------------|-------------|---------------|
|      1      |      1      |     150.00    |
|      2      |      1      |     200.00    |
|      1      |      2      |     100.00    |
|      2      |      2      |     300.00    |
|      3      |      2      |     250.00    |

 
 
 
 

그룹화와 집계 함수

 
MySQL의 GROUP BY 절은 집계 함수와 함께 사용할 수 있습니다. 다음 예제에서는 'employees' 테이블에서 각 부서의 평균 연봉을 계산해 보겠습니다.
 
 

-- 예시: 부서별 평균 연봉 계산
CREATE TABLE employees (
    employee_id INT,
    department VARCHAR(100),
    salary DECIMAL(10, 2)
);

INSERT INTO employees (employee_id, department, salary) VALUES
(1, 'HR', 60000),
(2, 'Engineering', 80000),
(3, 'HR', 65000),
(4, 'Engineering', 90000),
(5, 'Marketing', 70000);

SELECT department, AVG(salary) AS average_salary
FROM employees
GROUP BY department;

 
 
위의 쿼리는 'employees' 테이블에서 'department'를 기준으로 데이터를 그룹화하고, 각 부서의 평균 연봉을 계산합니다.
 
 

[RESULT]

| department   | average_salary |
|--------------|----------------|
| HR           |      62500.00  |
| Engineering  |      85000.00  |
| Marketing    |      70000.00  |

 
 
 
 

조건부 그룹화

 
HAVING 절을 사용하면 그룹화된 데이터에 조건을 적용할 수 있습니다. 다음 예제에서는 'sales' 테이블에서 총 판매량이 200 이상인 제품만 선택해 보겠습니다.
 
 
 

-- 예시: 총 판매량이 200 이상인 제품 선택
SELECT product_id, SUM(sale_amount) AS total_sales
FROM sales
GROUP BY product_id
HAVING total_sales >= 200;

 
 
위의 쿼리는 'sales' 테이블에서 'product_id'를 기준으로 데이터를 그룹화하고, 총 판매량이 200 이상인 제품만 선택합니다.
 
 

[RESULT]

| product_id | total_sales |
|------------|-------------|
|     1      |    250.50   |
|     2      |    251.00   |
|     3      |    300.00   |

 
 
 
 

복합 집계 함수 사용

 
MySQL에서는 여러 집계 함수를 함께 사용할 수 있습니다. 다음 예제에서는 'orders' 테이블에서 각 고객의 주문 수와 총 주문 금액을 계산해 보겠습니다.
 
 
 

-- 예시: 고객별 주문 수와 총 주문 금액 계산
SELECT customer_id, COUNT(*) AS order_count, SUM(order_amount) AS total_order_amount
FROM orders
GROUP BY customer_id;

 
 
위의 쿼리는 'orders' 테이블에서 'customer_id'를 기준으로 데이터를 그룹화하고, 각 고객의 주문 수와 총 주문 금액을 계산합니다. 
 
 

[RESULT]

| customer_id | order_count | total_order_amount |
|-------------|-------------|--------------------|
|      1      |      2      |        250.00      |
|      2      |      2      |        500.00      |
|      3      |      1      |        250.00      |

 
 
 
 
 


집계함수 종류

 

집계 함수설명사용 예시결과 예시
COUNT()그룹의 행 수를 반환SELECT department, COUNT(*) FROM employees
GROUP BY department;
각 부서의 직원 수
SUM()그룹의 합계를 반환SELECT department, SUM(salary) FROM employees
GROUP BY department;
각 부서의 총 연봉 합계
AVG()그룹의 평균값을 반환SELECT department, AVG(salary) FROM employees
GROUP BY department;
각 부서의 평균 연봉
MAX()그룹의 최대값을 반환SELECT department, MAX(salary) FROM employees
GROUP BY department;
각 부서의 최대 연봉
MIN()그룹의 최소값을 반환SELECT department, MIN(salary) FROM employees
GROUP BY department;
각 부서의 최소 연봉
STDDEV()그룹의 표준 편차를 반환SELECT department, STDDEV(salary) FROM employees
GROUP BY department;
각 부서의 연봉 표준 편차
VARIANCE()그룹의 분산을 반환SELECT department, VARIANCE(salary) FROM employees GROUP BY department;각 부서의 연봉 분산

 
 
 
 
 


 
이상으로 MySQL 데이터 정렬 및 부분 조회 방법, 데이터 그룹화에 대해 알아보았습니다.