GROUP BY
데이터를 그룹화 하고 싶을 때 GROUP BY 문을 사용하고 일반적으로 HAVING도 같이 사용한다.
HAVING : WHERE과 비슷한 역할을 하며 그룹화된 데이터를 필터링 한다.
다음 아래에 회원 테이블 생성 및 회원 쿼리문 예제로 실습을 진행한다.
회원 테이블 생성 쿼리문
CREATE TABLE `member` (
`mb_id` varchar(20) NOT NULL,
`mb_password` varchar(255) NOT NULL,
`mb_name` varchar(50) NOT NULL,
`mb_email` varchar(100) NOT NULL,
`mb_hp` varchar(20) DEFAULT NULL,
`mb_tel` varchar(20) DEFAULT NULL,
`mb_addr` varchar(255) DEFAULT NULL,
`mb_birth` date DEFAULT NULL,
`mb_sex` char(1) DEFAULT NULL,
`mb_level` int DEFAULT '1', PRIMARY KEY (`mb_id`)
);
회원 데이터
INSERT INTO `member` (`mb_id`, `mb_password`, `mb_name`, `mb_email`, `mb_hp`, `mb_tel`, `mb_addr`, `mb_birth`, `mb_sex`, `mb_level`) VALUES
('user001', 'password123', '홍길동', 'hong1@example.com', '010-1111-2222', '02-123-4567', '서울시 강남구', '1990-05-12', 'M', 1),
('user002', 'password456', '김영희', 'kim2@example.com', '010-2233-4455', '031-789-1234', '경기도 수원시', '1992-07-23', 'F', 2),
('user003', 'password789', '이철수', 'lee3@example.com', '010-3344-5566', '032-456-7890', '부산시 해운대구', '1985-10-30', 'M', 3),
('user004', 'password012', '박지영', 'park4@example.com', '010-4455-6677', '033-567-8901', '인천시 부평구', '1995-03-15', 'F', 1),
('user005', 'password345', '최민수', 'choi5@example.com', '010-5566-7788', '042-678-9012', '대전시 서구', '1993-12-05', 'M', 2),
('user006', 'password678', '윤수진', 'yoon6@example.com', '010-6677-8899', '052-789-0123', '울산시 남구', '1988-01-19', 'F', 1),
('user007', 'password901', '오세훈', 'oh7@example.com', '010-7788-9900', '061-890-1234', '광주시 북구', '1987-08-22', 'M', 3),
('user008', 'password234', '한지민', 'han8@example.com', '010-8899-0011', '051-901-2345', '경상북도 포항시', '1991-04-28', 'F', 1),
('user009', 'password567', '서지수', 'seo9@example.com', '010-9900-1122', '063-234-5678', '전주시 완산구', '1994-06-13', 'F', 2),
('user010', 'password890', '장우진', 'jang10@example.com', '010-1122-3344', '02-123-4567', '서울시 종로구', '1986-09-02', 'M', 1),
('user011', 'passwordabc', '김민지', 'kim11@example.com', '010-2233-4455', '031-567-8901', '경기도 안양시', '1990-11-11', 'F', 2),
('user012', 'passworddef', '조수미', 'cho12@example.com', '010-3344-5566', '032-456-7890', '부산시 동래구', '1985-05-23', 'F', 3),
('user013', 'passwordghi', '임윤호', 'lim13@example.com', '010-4455-6677', '033-678-9012', '인천시 송도구', '1992-01-14', 'M', 1),
('user014', 'passwordjkl', '오미정', 'oh14@example.com', '010-5566-7788', '042-789-0123', '대전시 유성구', '1994-09-30', 'F', 2),
('user015', 'passwordmno', '한상우', 'han15@example.com', '010-6677-8899', '052-890-1234', '울산시 울주군', '1993-02-02', 'M', 1),
('user016', 'passwordpqr', '최진영', 'cho16@example.com', '010-7788-9900', '061-123-4567', '광주시 서구', '1990-08-19', 'F', 3),
('user017', 'passwordstu', '윤진우', 'yoon17@example.com', '010-8899-0011', '051-234-5678', '경상북도 경주시', '1987-12-11', 'M', 2),
('user018', 'passwordvwx', '김하늘', 'kim18@example.com', '010-9900-1122', '063-567-8901', '전라북도 군산시', '1995-06-25', 'F', 1),
('user019', 'passwordyz1', '장우석', 'jang19@example.com', '010-1122-3344', '02-567-8901', '서울시 마포구', '1991-10-14', 'M', 2),
('user020', 'password1234', '박수현', 'park20@example.com', '010-2233-4455', '031-890-1234', '경기도 화성시', '1992-03-01', 'F', 1);
GROUP BY 기본 형식
SELECT [열] FROM [테이블명] WHERE [열] = [조건값] GROUP BY [열] HAVING [열] = [조건값]
※ SELECT하는 열과 GROUP BY의 열은 같아야 한다
회원 권한을 그룹화
mysql> select mb_level from member group by mb_level;
+----------+
| mb_level |
+----------+
| 1 |
| 2 |
| 3 |
+----------+
회원 권한을 중복만 제거하여 출력
mysql> select distinct mb_level from member;
+----------+
| mb_level |
+----------+
| 1 |
| 2 |
| 3 |
+----------+
3 rows in set (0.00 sec)
※ DISTINCT는 단순히 중복만 제거하기때문에 계산이 필요하다면 GROUP BY를 사용해야한다.
COUNT
그룹화한 튜플의 데이터 개수를 카운트
SELECT [컬럼1], COUNT(*) FROM [테이블명] GROUP BY [컬럼1]
SELECT [컬럼1], COUNT(*) AS CNT FROM [테이블명] GROUP BY [컬럼1]
AS(alias)
alias는 별칭을 뜻하며 필드명, 테이블 명에 붙일 수 있다
SELECT mb_level AS lv, mb_addr AS addr from member AS mb limit 5;
mysql> SELECT mb_level AS lv, mb_addr AS addr from member AS mb limit 5;
+------+-----------------+
| lv | addr |
+------+-----------------+
| 1 | 서울시 강남구 |
| 2 | 경기도 수원시 |
| 3 | 부산시 해운대구 |
| 1 | 인천시 부평구 |
| 2 | 대전시 서구 |
+------+-----------------+
5 rows in set (0.00 sec)
member 테이블에 mb_sex 컬럼의 카운트
mysql> select mb_level, mb_sex, count(*) as cnt from member group by mb_level, mb_sex order by mb_level asc;
+----------+--------+-----+
| mb_level | mb_sex | cnt |
+----------+--------+-----+
| 1 | F | 5 |
| 1 | M | 4 |
| 2 | F | 4 |
| 2 | M | 3 |
| 3 | F | 2 |
| 3 | M | 2 |
+----------+--------+-----+
6 rows in set (0.00 sec)
HAVING
GROUP BY는 WHERE절을 사용할 수 없기 때문에 HAVING을 사용한다
mb_level과 mb_sex로 그룹화하고 mb_level이 1인 데이터 조회
mysql> select mb_level, mb_sex, count(*) as cnt from member group by mb_level, mb_sex having mb_level = 1;
+----------+--------+-----+
| mb_level | mb_sex | cnt |
+----------+--------+-----+
| 1 | M | 4 |
| 1 | F | 5 |
+----------+--------+-----+
2 rows in set (0.00 sec)
mb_sex, mb_name, mb_birth를 그룹화하고 성별이 남자인 회원만 생년월일 오름차 순으로 조회
mysql> select mb_sex, mb_name, mb_birth from member group by mb_sex, mb_name, mb_birth having mb_sex = 'M' order by mb_birth asc;
+--------+---------+------------+
| mb_sex | mb_name | mb_birth |
+--------+---------+------------+
| M | 이철수 | 1985-10-30 |
| M | 장우진 | 1986-09-02 |
| M | 오세훈 | 1987-08-22 |
| M | 윤진우 | 1987-12-11 |
| M | 홍길동 | 1990-05-12 |
| M | 장우석 | 1991-10-14 |
| M | 임윤호 | 1992-01-14 |
| M | 한상우 | 1993-02-02 |
| M | 최민수 | 1993-12-05 |
+--------+---------+------------+
9 rows in set (0.00 sec)
'MYSQL' 카테고리의 다른 글
[MYSQL][08] ALTER (1) | 2024.11.27 |
---|---|
[MYSQL][07] ORDER BY (0) | 2024.11.26 |
[MYSQL][06] 외래키(Foreign Key, FK)의 참조 무결성 (0) | 2024.11.25 |
[MYSQL][05] KEY (0) | 2024.11.24 |
[MYSQL][04] SELECT (0) | 2024.11.22 |