SELECT 문으로 검색한 결과를 특정 컬럼을 기준으로 그룹화하기 위해 GROUP BY 절을 사용하며, 그룹별로 정렬을 수행하거나 집계 함수를 사용하여 그룹별 집계를 구할 때 사용한다. 그룹이란 GROUP BY 절에 명시된 컬럼에 대해 동일한 컬럼 값을 가지는 레코드들을 의미한다.
GROUP BY 절 뒤에 HAVING 절을 결합하여 그룹 선택을 위한 조건식을 설정할 수 있다. 즉, GROUP BY 절로 구성되는 모든 그룹 중 HAVING 절에 명시된 조건식을 만족하는 그룹만 조회한다.
SQL 표준에서는 GROUP BY 절에서 명시되지 않은 컬럼(hidden column)을 SELECT 컬럼 리스트에 명시할 수 없지만, CUBRID는 문법을 확장하여 GROUP BY 절에서 명시되지 않은 컬럼도 SELECT 컬럼 리스트에 명시할 수 있다. CUBRID에서 확장된 문법을 사용하지 않으려면 only_full_group_by 파라미터 값을 yes로 설정해야 한다. 이에 대한 자세한 내용은 구문/타입 관련 파라미터를 참고한다.
SELECT ...
GROUP BY { col_name | expr | positoin } [ ASC | DESC ],...
[ WITH ROLLUP ][ ORDER BY NULL ][ HAVING <search_condition> ]
--creating a new table
CREATE TABLE sales_tbl
(dept_no int, name VARCHAR(20) PRIMARY KEY, sales_month int, sales_amount int DEFAULT 100);
INSERT INTO sales_tbl VALUES
(201, 'George' , 1, 450),
(201, 'Laura' , 2, 500),
(301, 'Max' , 4, 300),
(501, 'Stephan', 4, DEFAULT),
(501, 'Chang' , 5, 150),
(501, 'Sue' , 6, 150),
(NULL, 'Yoka' ,4, NULL);
--selecting rows grouped by dept_no with ORDER BY NULL modifier
SELECT dept_no, avg(sales_amount) FROM sales_tbl
GROUP BY dept_no ORDER BY NULL;
dept_no avg(sales_amount)
================================
NULL NULL
201 475
301 300
501 133
--conditions in WHERE clause operate first before GROUP BY
SELECT dept_no, avg(sales_amount) FROM sales_tbl
WHERE sales_amount > 100 GROUP BY dept_no;
dept_no avg(sales_amount)
================================
201 475
301 300
501 150
--conditions in HAVING clause operate last after GROUP BY
SELECT dept_no, avg(sales_amount) FROM sales_tbl
WHERE sales_amount > 100 GROUP BY dept_no HAVING avg(sales_amount) > 200;
dept_no avg(sales_amount)
================================
201 475
301 300
--selecting and sorting rows with using column alias
SELECT dept_no AS a1, avg(sales_amount) AS a2 FROM sales_tbl
WHERE sales_amount > 200 GROUP BY a1 HAVING a2 > 200 ORDER BY a2;
a1 a2
==========================
301 300
201 475
--selecting rows grouped by dept_no with WITH ROLLUP modifier
SELECT dept_no AS a1, name AS a2, avg(sales_amount) AS a3 FROM sales_tbl
WHERE sales_amount > 100 GROUP BY a1,a2 WITH ROLLUP;
a1 a2 a3
================================================
201 'George' 450
201 'Laura' 500
201 NULL 475
301 'Max' 300
301 NULL 300
501 'Chang' 150
501 'Sue' 150
501 NULL 150
NULL NULL 310