
이번 포스팅에서는 SQL 구문 GROUP BY, HAVING 그리고 ORDER BY를 알아보도록 하겠습니다.
GROUP BY
GROUP BY는 동일한 범주를 갖는 데이터를 하나로 묶어주는 구문이에요. 주로 그룹 별 데이터를 집계할 때 사용하죠.

SELECT + [컬럼]
FROM + [테이블]
GROUP BY + [컬럼];
GROUP BY를 구문에 있는 컬럼은 반드시 SELECT 절에도 존재해야 합니다. GROUP BY 컬럼이 아닌 컬럼을 SELECT 할 경우 에러가 날 수 있어요. 이는 쿼리 실행 순서가 FROM → GROUP BY → SELECT 순이기 때문이에요.
- FROM [테이블] : [테이블] 데이터 전체를 가져와서
- GROUP BY [컬럼] : [테이블] 데이터에서 같은 [컬럼]을 갖는 데이터를 합치고
- select [컬럼] : [컬럼]에 따라 합쳐진 데이터를 추출한다.
GROUP BY 구문은 집계함수와도 종종 함께 사용합니다.
| 함수 | 뜻 | 설명 |
| SUM(칼럼) | 합계 | 칼럼 내에 NULL값을 제외한 합계값을 반환 |
| AVG | 평균 | 칼럼 내에 NULL값을 제외한 평균값을 반환 |
| MAX | 최댓값 | 칼럼 내의 최댓값을 반환 |
| MIN | 최솟값 | 칼럼 내의 최솟값을 반환 |
[예제]
▼ order 테이블
| name | phone | order_type | order_name | order_code |
| 홍길동 | 010-1234-5678 | BN | 닌텐도스위치 OLED | BN100123213 |
| 홍길순 | 010-5678-1234 | BN | 갤럭시워치 4 44mm | BN123123212 |
| 김지수 | 010-0000-0001 | BN | 아이패드SE 64GB | BN100339393 |
| 윤다영 | 010-0000-1231 | BR | 닌텐도스위치 OLED | BR100194941 |
Q. 상품별로 구매한 유저들이 몇 명인지 알려주세요.
SELECT order_name , COUNT (*)
FROM order
GROUP BY order_name;
이 쿼리를 해석해보면,
- FROM order : order 데이터 전체를 가져와서
- GROUP BY order_type : order 데이터에서 같은 order_name 을 갖는 데이터를 합치고
- select order_name , count(*) : order_name별 수를 파악한다.
가 되겠네요.
[결과]
| order_name | count(*) |
| 닌텐도스위치 OLED | 2 |
| 갤럭시워치 4 44mm | 1 |
| 아이패드SE 64GB | 1 |
HAVING
HAVING은 GROUP BY로 그룹화된 값에 조건식을 적용할 때 사용해요.
SELECT + [컬럼]
FROM + [테이블]
GROUP BY + [컬럼];
HAVING + [조건식]
앞서 배운 WHERE 구문과 조건을 제한한다는 점에서는 비슷하지만,
- WHERE 구문은 테이블 전체에 조건을 거는 것
- HAVING 구문은 그룹화된 값에 조건을 거는 것
이라는 점에서 차이가 있어요. HAVING 구문은 GROUP BY 구문과 함께만 사용할 수 있으며, 항상 GROUP BY 구문 다음에 나와야해요.
ORDER BY
ORDER BY 는 가져온 데이터를 정렬해주는 구문이에요. 기본적으로는 오름차순으로 정렬하고, DESC 키워드를 추가할 경우 내림차순으로 정렬됩니다. ORDER BY 는 항상 SELECT 문의 맨 마지막에 위치합니다. 쿼리 순서는 FROM → GROUP BY → SELECT → ORDER BY 순이에요.

SELECT + [컬럼]
FROM + [테이블]
ORDER BY + [컬럼] (ASC); ▶︎ 오름차순
ORDER BY + [컬럼] DESC; ▶︎ 내림차순
[예제]
▼ user_profile 테이블
| name | phone | gender | join_date | last_login_date | info_term_agreement |
| 홍길동 | 010-1234-5678 | 남 | 2023-01-12 | 2023-02-02 | 1 |
| 홍길순 | 010-5678-1234 | 여 | 2023-02-01 | 2023-02-01 | 0 |
| 김지수 | 010-0000-0001 | 여 | 2022-12-23 | 2023-02-11 | 1 |
| 윤다영 | 010-0000-1231 | 여 | 2021-07-21 | 2021-12-01 | 1 |
Q. 로그인 한지 오래된 순으로 유저 리스트를 뽑아주세요.
SELECT *
FROM user_profile
ORDER BY last_login_date;
Q. 최근 로그인 날짜 순으로 유저 리스트를 뽑아주세요.
SELECT *
FROM user_profile
ORDER BY last_login_date DESC;
만약 여러 컬럼을 정렬하고 싶으면 어떻게 해야할까요? 간단합니다. 콤마(,)로 이어나가면 돼요.
SELECT + [컬럼]
FROM + [테이블]
ORDER BY + [컬럼1],[컬럼2],[컬럼3] ....
여러 컬럼을 정렬할 경우, 가장 왼쪽 값부터 순차적으로 정렬이 되기 때문에 우선순위가 높은 순서대로 나열하는 것이 좋아요.
[예제]
| ID | name | grade | age |
| 1 | 박수홍 | 85 | 17 |
| 2 | 서지은 | 90 | 18 |
| 3 | 유인나 | 87 | 17 |
| 4 | 김지영 | 95 | 18 |
Q. "등급"을 기준으로 내림차순으로 데이터를 정렬한 다음 "나이"를 기준으로 오름차순하세요.
SELECT *
FROM students
ORDER BY grade DESC, age ASC;
| ID | name | grade | age |
| 4 | 김지영 | 95 | 18 |
| 2 | 서지은 | 90 | 18 |
| 3 | 유인나 | 87 | 17 |
| 1 | 박수홍 | 85 | 17 |
보시다시피 데이터가 ①먼저 "등급"별로 내림차순으로 정렬되므로 가장 높은 등급이 먼저 표시되고 ②각 등급 내에서 "나이"별로 오름차순으로 표시돼요.
이번 포스팅에서는 데이터를 그룹화하고 정렬하는 구문에 대해 배워봤습니다. 사실 여기까지만 알아도 간단한 데이터 추출은 모두 가능하실텐데요. 다음 포스팅에서는 제가 SQL에서 가장 많이 사용하는 JOIN 구문에 대해 소개해 보겠습니다. 안녕 !
'DATA' 카테고리의 다른 글
| 마케터를 위한 통계 | 마케터한테 기본적인 통계 기초가 필요한 이유 (0) | 2024.03.12 |
|---|---|
| 마케터를 위한 실무 SQL 노트 ④ JOIN (0) | 2023.02.26 |
| 마케터를 위한 실무 SQL 노트 ② SELECT,WHERE (0) | 2023.02.12 |
| 마케터를 위한 실무 SQL 노트 ① SQL을 공부해야 하는 이유 (0) | 2023.02.05 |
| 넷플릭스의 언택트마케팅 : ' 넷플릭스 파티 (Netflix Party) ' (0) | 2020.03.28 |