SQL 에서 데이터에 대해 어떠한 조작이나 계산을 수행하려면 '함수' 라는 도구를 사용한다.
함수는 크게 2 종류로 나뉜다.
복수 행에 대해 집계를 수행하는 함수
단일 행의 값에 대해 조작이나 계산을 수행하는 함수
전자의 경우 '집약함수(집계함수)' 라 부른다.
COUNT 테이블의 행수를 알려주는 함수
SUM 테이블의 수치 데이터를 합계하는 함수
AVG 테이블의 수치 데이터 평균을 구하는 함수
MAX 테이블의 임의열 데이터 중 최대값을 구하는 함수
MIN 테이블의 임의열 데이터 중 최소값을 구하는 함수
이러한 집약함수는 기본적으로 NULL을 제외하고 집계하는데, COUNT 함수만은 'COUNT(*)' 로 표기하여 NULL을 포함한 전체 행을 집계한다. 또한, SUM, AVG 이외의 집약함수는 수치 데이터 외에도 이용 가능하다. 예를 들어, 도시명 최대값은 'Y' 로 시작하는 'Yosu', 최소값은 'A' 로 시작하는 'Andong' 이 된다.
mysql>selectnamefrom city where countrycode ='KOR';+------------+| name |+------------+| Seoul || Pusan || Inchon |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| Yongchon || Sachon || Uiwang || Naju || Namwon || Tonghae || Mun-gyong |+------------+70rowsinset (0.00 sec)mysql>selectmax(name) from city where countrycode ='KOR';+-----------+| max(name) |+-----------+| Yosu |+-----------+1rowinset (0.00 sec)mysql>selectmin(name) from city where countrycode ='KOR';+-----------+| min(name) |+-----------+| Andong |+-----------+1rowinset (0.00 sec)
문자열을 집약하는 GROUP_CONCAT
문자열에 대한 집약함수는 SQL 표준에는 없으나 MySQL에는 'GROUP_CONCAT' 함수가 있다. 'GROUP_CONCAT' 함수는 콤마로 구분되는 문자열의 결합을 돌려준다. 만약 애플리케이션 측에서 사용시에는 함수 결과가 매우 길 수 있어 주의해야 한다.
mysql>select group_concat(name) from city where countrycode ='KOR'and district ='Chollabuk';+-------------------------------------------+| group_concat(name) |+-------------------------------------------+| Chonju,Iksan,Kunsan,Chong-up,Kimje,Namwon |+-------------------------------------------+1rowinset (0.00 sec)
DISTINCT로 중복 회피
DISTINCT 는 선택한 행의 중복을 배제하고 싶은 경우에 이용하는데, 집약함수에도 이용할 수 있다.
'조건'이 있다면 WHERE 구문에 조건을 추가하고 싶지만 오류가 발생한다. COUNT 같은 집약함수를 작성할 수 있는 경우는 SELECT와 ORDER BY, HAVING 뿐이다.
mysql>select district, count(*) from city where countrycode ='KOR'andcount(*) =4group by district;ERROR 1111 (HY000): Invalid use of group function
집약한 결과에 조건 지정
그룹마다 집약한 값을 조건으로 선택하고 싶다면 HAVING 뒤에 조건을 지정해야 한다.
SELECT ~ FROM ~ GROUP BY ~ HAVING 그룹의 값에 대한 조건
mysql>select district, count(*) from city where countrycode ='KOR'group by district havingcount(*) =6;+---------------+----------+| district | count(*) |+---------------+----------+| Chollabuk | 6 || Chungchongnam | 6 |+---------------+----------+2rowsinset (0.00 sec)
또한, 앞에서 말한대로 SELECT와 ORDER BY 에도 집약함수를 기술 할 수 있다.
mysql> select district, count(*) from city where countrycode = 'KOR' group by district having count(*) > 6 order by count(*) desc;
+--------------+----------+| district | count(*) |+--------------+----------+| Kyonggi | 18 || Kyongsangnam | 11 || Kyongsangbuk | 10 |+--------------+----------+3rowsinset (0.00 sec)