SELECT 문을 응용해보자
검색결과 정렬
SELECT ~ ORDER BY 열1 [ , 열2, ... ]
ORDER BY 에 사용한 열명을 '정렬키' 라고 한다.
오름차순 ASC (디폴)
내림차순 DESC
테이블을 요약하는 함수
SQL 에서 데이터에 대해 어떠한 조작이나 계산을 수행하려면 '함수' 라는 도구를 사용한다.
함수는 크게 2 종류로 나뉜다.
복수 행에 대해 집계를 수행하는 함수
단일 행의 값에 대해 조작이나 계산을 수행하는 함수
전자의 경우 '집약함수(집계함수)' 라 부른다.
COUNT 테이블의 행수를 알려주는 함수
SUM 테이블의 수치 데이터를 합계하는 함수
AVG 테이블의 수치 데이터 평균을 구하는 함수
MAX 테이블의 임의열 데이터 중 최대값을 구하는 함수
MIN 테이블의 임의열 데이터 중 최소값을 구하는 함수
이러한 집약함수는 기본적으로 NULL을 제외하고 집계하는데, COUNT 함수만은 'COUNT(*)' 로 표기하여 NULL을 포함한 전체 행을 집계한다. 또한, SUM, AVG 이외의 집약함수는 수치 데이터 외에도 이용 가능하다. 예를 들어, 도시명 최대값은 'Y' 로 시작하는 'Yosu', 최소값은 'A' 로 시작하는 'Andong' 이 된다.
mysql> select name from city where countrycode = 'KOR';
+------------+
| name |
+------------+
| Seoul |
| Pusan |
| Inchon |
~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~
| Yongchon |
| Sachon |
| Uiwang |
| Naju |
| Namwon |
| Tonghae |
| Mun-gyong |
+------------+
70 rows in set (0.00 sec)
mysql> select max(name) from city where countrycode = 'KOR';
+-----------+
| max(name) |
+-----------+
| Yosu |
+-----------+
1 row in set (0.00 sec)
mysql> select min(name) from city where countrycode = 'KOR';
+-----------+
| min(name) |
+-----------+
| Andong |
+-----------+
1 row in set (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 |
+-------------------------------------------+
1 row in set (0.00 sec)
DISTINCT로 중복 회피
DISTINCT 는 선택한 행의 중복을 배제하고 싶은 경우에 이용하는데, 집약함수에도 이용할 수 있다.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| group_concat(district) |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Seoul,Pusan,Inchon,Taegu,Taejon,Kwangju,Kyongsangnam,Kyonggi,Kyonggi,Kyonggi,Kyonggi,Chollabuk,Chungchongbuk,Kyonggi,Kyonggi,Kyongsangbuk,Kyongsangnam,Kyongsangnam,Kyonggi,Chungchongnam,Kyongsangnam,Chollabuk,Kyonggi,Kyongsangbuk,Kyonggi,Kyongsangbuk,Chollabuk,Cheju,Kyongsangnam,Chollanam,Chollanam,Kyonggi,Kang-won,Kyonggi,Kang-won,Kyonggi,Kang-won,Chungchongbuk,Kyongsangbuk,Chollanam,Kyongsangbuk,Kyonggi,Kyongsangnam,Kyonggi,Chungchongnam,Kyongsangnam,Kyongsangbuk,Chungchongnam,Kyonggi,Chollabuk,Chungchongbuk,Chungchongnam,Kyonggi,Kyongsangnam,Chungchongnam,Kyongsangbuk,Kyongsangnam,Kyongsangbuk,Chungchongnam,Chollanam,Kyongsangnam,Kyonggi,Chollabuk,Kyongsangbuk,Kyongsangnam,Kyonggi,Chollanam,Chollabuk,Kang-won,Kyongsangbuk |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> select group_concat(distinct district) from city where countrycode = 'KOR';
+------------------------------------------------------------------------------------------------------------------------------------------+
| group_concat(distinct district) |
+------------------------------------------------------------------------------------------------------------------------------------------+
| Cheju,Chollabuk,Chollanam,Chungchongbuk,Chungchongnam,Inchon,Kang-won,Kwangju,Kyonggi,Kyongsangbuk,Kyongsangnam,Pusan,Seoul,Taegu,Taejon |
+------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
데이터를 그룹으로 나누는 GROUP BY
대상이 되는 데이터를 몇 개의 그룹으로 나눠서 집약하는 것도 가능하다. 예를 들어, '행정구역(district) 마다', '국가(country) 마다' 집약하는 식이다.
SELECT ~ FROM 테이블명 GROUP BY 열명1 [ , 열명2, ... ]
GROUP BY 로 지정한 열을 '집약 키' 또는 '그룹화 키' 로 부르며, 복수 열을 콤마로 구분해 지정할 수 도 있다.
mysql> select count(*) from city where countrycode = 'KOR';
+----------+
| count(*) |
+----------+
| 70 |
+----------+
1 row in set (0.00 sec)
mysql> select district, count(*) from city where countrycode = 'KOR' group by district;
+---------------+----------+
| district | count(*) |
+---------------+----------+
| Seoul | 1 |
| Pusan | 1 |
| Inchon | 1 |
| Taegu | 1 |
| Taejon | 1 |
| Kwangju | 1 |
| Kyongsangnam | 11 |
| Kyonggi | 18 |
| Chollabuk | 6 |
| Chungchongbuk | 3 |
| Kyongsangbuk | 10 |
| Chungchongnam | 6 |
| Cheju | 1 |
| Chollanam | 5 |
| Kang-won | 4 |
+---------------+----------+
15 rows in set (0.00 sec)
나눈 그룹에 조건 추가
그룹으로 나눠서 집약한 값에 대해 조건을 설정하려면 어떻게 해야 할까?
'조건'이 있다면 WHERE 구문에 조건을 추가하고 싶지만 오류가 발생한다. COUNT 같은 집약함수를 작성할 수 있는 경우는 SELECT와 ORDER BY, HAVING 뿐이다.
mysql> select district, count(*) from city where countrycode = 'KOR' and count(*) = 4 group 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 having count(*) = 6;
+---------------+----------+
| district | count(*) |
+---------------+----------+
| Chollabuk | 6 |
| Chungchongnam | 6 |
+---------------+----------+
2 rows in set (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 |
+--------------+----------+
3 rows in set (0.00 sec)
SELECT 문의 작성 순서는 다음과 같다.
SELECT ~ FROM ~ GROUP BY ~ HAVING ~ ORDER BY ~
Last updated
Was this helpful?