해당 글에서는 필터링하고 정렬하는데 사용되는 GROUP BY, ORDER BY, LIMIT에 대해서 이해를 돕기 위해 사용하는 SQL 절에 대해서 이해를 돕기 위해 작성한 글입니다.
1) SQL 수행 순서
1. SQL 수행 구조
💡 GROUP BY, ORDER BY, LIMIT 해당 부분을 포함하여 SQL문이 실행되는 순서를 확인합니다.

SELECT 컬럼명 -- 6
FROM 테이블 -- 1
WHERE 조건절 -- 2
GROUP BY 그룹화 -- 3
HAVING 그룹 조건절 -- 4
ORDER BY 정렬 -- 5
LIMIT 제한수 -- 7
💡 [SQL문 수행 순서] : FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT
수행 순서 | SQL 절 | 설명 |
1 | FROM | SELECT 문에 필요한 테이블 선택 |
2 | WHERE | WHERE 조건절을 이용하여 행(row) 데이터 필터링 |
3 | GROUP BY | GROUP BY 절을 이용하여 특정 컬럼의 그룹화를 수행 |
4 | HAVING | HAVING 절을 이용하여 그룹화된 결과에 대한 조건 필터링 |
5 | SELECT | SELECT 절에서 사용할 컬럼 선택 |
6 | ORDER BY | ORDER BY 절을 이용하여 결과 데이터 정렬 |
7 | LIMIT | LIMIT 절을 이용하여 출력할 데이터의 개수 제한 |
2. SQL 수행 순서 예시
SELECT category, SUM(sales)
FROM sales_data
WHERE date BETWEEN '2022-01-01' AND '2022-01-31'
GROUP BY category
HAVING SUM(sales) > 10000
ORDER BY SUM(sales) DESC
LIMIT 5;
수행 순서 | SQL 절 | 설명 |
1 | FROM | sales_data 테이블 선택 |
2 | WHERE | date 컬럼이 2022년 1월인 데이터 필터링 |
3 | GROUP BY | category 컬럼을 기준으로 그룹화 |
4 | HAVING | sales 컬럼의 합계가 10000 이상인 그룹 필터링 |
5 | SELECT | category와 SUM(sales) 컬럼 선택 |
6 | ORDER BY | SUM(sales) 기준으로 결과 데이터 내림차순 정렬 |
7 | LIMIT | 결과 데이터 중 상위 5개만 출력 |
2) GROUP BY ~ HAVING 절

💡 GROUP BY란?
- SQL에서 데이터를 ‘그룹화’하는 데 사용되는 절입니다. 이 절은 특정 열(Colum)의 값을 기준으로 행(Row)을 그룹화하거나 각 그룹에 대한 집계 함수로 계산을 합니다.
💡 HAVING 이란?
- SQL에서 그룹화 된 결과 집합에 대한 ‘조건’을 지정하는데 사용됩니다.
- WHERE절과 유사하지만 WHERE절은 단일 행에 대한 조건을 지정하는데 사용되지만 HAVING절은 ‘그룹에 대한 조건’을 지정하는데 사용됩니다.
= 그룹/집계함수(MAX, MIN, AVG, COUNT 등)를 포함한 그룹화된 결과에 대한 조건을 지정하며 결과 집합에서 필터링을 하는데 사용됩니다.
[ 더 알아보기 ]
💡집계 함수(Aggregate Function)란?
- 데이터베이스에서 데이터를 그룹화하고 집계(합계, 평균, 최대값, 최소값 등)를 계산하기 위한 함수입니다. 대표적인 집계 함수로는 SUM, AVG, MAX, MIN, COUNT 등이 있습니다.
💡 [참고] 집계함수의 종류
집계 함수 | 설명 |
COUNT | 그룹 내 행 수를 계산 |
SUM | 그룹 내 특정 열의 합계 계산 |
AVG | 그룹 내 특정 열의 평균 계산 |
MAX | 그룹 내 특정 열의 최댓값 계산 |
MIN | 그룹 내 특정 열의 최솟값 계산 |
1. GROUP BY ~ HAVING 구문
SELECT {column1}, {column2}, ..., {aggregate function(column)}
FROM {table}
GROUP BY {column1}, {column2}, ...
HAVING {condition}
SQL 절 | 설명 |
SELECT | 출력할 열(column) 이름을 지정하거나 집계 함수를 이용하여 지정합니다. |
FROM | 조회할 테이블 이름을 지정합니다. |
WHERE | 데이터를 조회할 때 필요한 조건을 지정합니다. |
GROUP BY | 그룹화할 열(column) 이름을 지정합니다. |
HAVING | 그룹화된 결과 데이터에 대한 조건을 지정합니다. |
2. GROUP BY ~ HAVING 예시
💡 [ 예시 설명 ]
- 해당 쿼리는 ProductID와 TotalOrders라는 두 개의 열을 반환합니다. TotalOrders는 각 제품에 대한 총 주문 수를 나타내며 HAVING 절에서 필터링되어 결과 집합에서는 주문 수가 10건 이상인 제품만 선택됩니다.
- HAVING 절은 그룹화된 결과에 대한 조건을 지정하는 데 사용되지만 그룹화되지 않은 결과에 대한 조건을 지정하는 데는 WHERE 절을 사용해야 합니다.
SELECT ProductID, SUM(Quantity) as TotalOrders
FROM Orders
GROUP BY ProductID
HAVING SUM(Quantity) >= 10;
3) ORDER BY

💡 ORDER BY 란?
- SQL문에서’ SELECT문의 결과를 정렬’하는 데 사용되는 구문을 의미합니다.
- 컬럼을 기준으로 ASC는 오름차순으로 정렬하고 DESC는 내림차순으로 정렬합니다.
- ASC는 Default 값으로 생략이 가능하다.
1. ORDER BY 구문
SELECT *
FROM table_name
ORDER BY column_name ASC/DESC;
SQL 절 | 설명 |
SELECT | 출력할 열(column) 이름을 지정하거나 집계 함수를 이용하여 지정합니다. |
FROM | 조회할 테이블 이름을 지정합니다. |
ORDER BY | - 데이터 조회 결과를 정렬합니다. - ASC는 오름차순으로 정렬하고 DESC는 내림차순으로 정렬합니다. |
[ 더 알아보기 ]
💡 ORDER BY를 이용하여 정렬할때 여러개의 컬럼을 기반으로 정렬이 가능한가?
- 가능합니다. 두 개 이상의 컬럼을 기반으로 정렬을 수행 할 수 있습니다.
💡 ORDER BY와 Full Scan의 관계
- SQL에서 ORDER BY는 질의 결과를 오름차순 또는 내림차순으로 정렬하는데 사용되는 절입니다. 일반적으로 ORDER BY 절을 실행하면 ‘Full Scan’으로 수행이 됩니다.
💡 Full Scan이란?
- 데이터베이스가 쿼리를 충족시키기 위해 테이블의 모든 행을 읽는 것입니다Full Scan의 경우는 인덱스가 없거나 인덱스를 효율적으로 사용 할 수 없을때 사용이 됩니다.
💡 Full Scan은 안 좋은것인가?
- ORDER BY에서 Full Scan으로 수행이 된다면 대규모 테이블의 경우는 모든 테이블의 행의 정보를 가져올 수 있기 때문에 비효율적으로 수행할 수 있습니다.쿼리의 성능을 향상시키기 위해서는 ‘인덱스’를 사용하는것이 좋습니다.
💡 DB의 index란?
- 데이터베이스에서 데이터 검색 속도를 향상시키기 위해 사용되는 자료구조입니다. 인덱스는 데이터베이스의 테이블에서 원하는 컬럼을 기준으로 생성됩니다. 이렇게 생성된 인덱스는 검색 시 해당 컬럼을 효율적으로 탐색하여 원하는 데이터를 빠르게 찾을 수 있도록 도와줍니다.
2. ORDER BY 예시
[ 예시 설명 ]
- 아래의 SQL문은 Customers라는 테이블에서 데이터를 모두 조회한 뒤 ORDER BY를 통해 Country라는 컬럼을 기준으로 내림차순(DESC)로 정렬을 수행하여 결과값을 반환합니다.
SELECT *
FROM Customers
ORDER BY Country DESC;
[ 예시 설명 ]
- 아래의 SQL문은 Customers라는 테이블에서 데이터를 모두 조회한 뒤 ORDER BY를 통해 Country 컬럼은 오름차순(ASC), City 컬럼은 오름차순(DESC)로 정렬을 수행하여 결과값을 반환합니다.
SELECT * FROM Customers ORDER BY Country ASC, City DESC;
4) LIMIT ~ OFFSET

💡 LIMIT란?
- SQL 쿼리 결과에서 가져올 ‘행의 최대 수를 정의’하는 키워드입니다.
💡OFFSET이란?
- SQL 쿼리 결과를 반환하기 전에 ‘지정된 수의 행을 건너 뛰는 데 사용’됩니다.
1. LIMIT ~ OFFSET 구문
SELECT *
FROM table_name
LIMIT {number_of_items} OFFSET {starting_point};
SQL 절 | 설명 |
SELECT | 출력할 열(column) 이름을 지정하거나 집계 함수를 이용하여 지정합니다. |
FROM | 조회할 테이블 이름을 지정합니다. |
LIMIT {number_of_items} | 결과 집합에서 표시 할 항목 수입니다. |
OFFSET {starting_point} | 결과 집합에서 시작 지점입니다. 기본값은 0입니다. |
2. LIMIT ~ OFFSET 예시
[ 예시 설명 ]
- 아래의 SQL문은 table의 모든 컬럼을 조회해옵니다. 조회된 값을 기반으로 21번째 row부터 30개의 row를 가져옵니다.
SELECT *
FROM table
LIMIT 10 OFFSET 20
3. LIMIT ~ OFFSET을 이용한 페이징(페이지네이션) 처리 : Offset-Based Pagination)
💡 SQL Limit와 Offset은 웹 애플리케이션에서 페이지네이션을 구현하는 데 자주 사용되는 기술입니다.
- LIMIT 절은 SELECT 문에서 반환되는 결과 수를 제한하는 데 사용되며 OFFSET 절은 결과를 반환하기 전에 지정된 수의 행을 건너 뛰는 데 사용됩니다.
[ 구조 ]
- LIMIT의 경우 ‘페이지 당 요청 자료 개수’로 사용이 됩니다.
- OFFSET의 경우 지정된 페이지 개수로 사용이 됩니다.
SELECT column1, column2
FROM table_name
LIMIT {perPage}
OFFSET {pageSize};
현재 페이지 | 페이지 당 요청 자료 개수(perPage) | 지정된 페이지 개수(pageSize) | 출력되는 데이터 |
1 | 20 | 0 | 0 - 20 데이터 |
2 | 20 | 20 | 21 - 40 데이터 |
3 | 20 | 40 | 41 - 60 데이터 |
4 | 20 | 60 | 61 - 80 데이터 |
[ 더 알아보기 ]
💡 OFFSET은 데이터셋이 큰 경우 매우 느려진다는데?
- WHERE 절을 이용하여서 사용하는 방법이나 CURSOR를 이용하는 방법도 존재합니다.
오늘도 감사합니다. 😀
'DB > 이론 및 문법' 카테고리의 다른 글
[DB/Postgres] PL/pgSQL 구성하기 -2 : DBeaver 기반 구축 및 활용 (0) | 2023.04.17 |
---|---|
[DB/Postgres] 테이블 스캔 -1 : 전체, 인덱스(전체, 범위, 고유, 루스, 병합) 스캔 (2) | 2023.04.09 |
[DB/Postgres] PL/pgSQL이해하기 -1 : Function, Stored Procedure (0) | 2023.04.08 |
[DB/Postgres] 서브쿼리(Subquery) / WITH 절 이해하기 -1 (0) | 2023.04.06 |
[DB/Postgres] 조인(JOIN) 이해하기 : 내부/외부 조인, UNION/UNION ALL (1) | 2023.04.04 |