일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- DP
- BOJ 1912
- BOJ 5791
- javascript
- Coercion
- MySQL
- serverless
- springboot
- BOJ 4485
- BOJ 1697
- BOJ 2213
- priority_queue
- BOJ 2012
- 다익스트라
- BOJ 2146
- 조합 알고리즘
- BOJ 6593
- Lambda
- BOJ 2167
- BOJ 4948
- BOJ 1926
- spring security
- BOJ 11726
- 플로이드 와샬
- BOJ 2407
- BOJ 1074
- AWS
- 분할과 정복
- BOJ 2234
- BOJ 5568
- Today
- Total
고인물을 지양하는 블로그
MySQL: SELECT_2 본문
데이터를 그룹으로 나누기
SELECT~ FROM 테이블명 GROUP BY 열명1,[열명2, ...]
지정한 그룹 열마다 집약해서 그룹 열로 나눈 그룹 수의 결과를 되돌려준다
select district, count(*) from city where countrycode="KOR" GROUP BY district;
+---------------+----------+
| district | count(*) |
+---------------+----------+
| Cheju | 1 |
| Chollabuk | 6 |
| Chollanam | 5 |
| Chungchongbuk | 3 |
| Chungchongnam | 6 |
...
| Kyonggi | 18 |
| Kyongsangbuk | 10 |
| Kyongsangnam | 11 |
| Pusan | 1 |
| Seoul | 1 |
| Taegu | 1 |
| Taejon | 1 |
+---------------+----------+
중복 제거
선택한 행의 값이 중복되어 이를 없애고 싶을 경우 DISTINCT를 사용한다.
select group_concat(district) from city where countrycode="KOR";
| 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, .... |
위와 같이 행정구역을 단순하게 GROUP_CONCAT한다면 중복 행정구역명이 여러 번 나타난다. 하지만, 아래와 같이 DISCTINCT를 사용하면
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 |
+------------------------------------------------------------------------------------------------------------------------------------------+
행정구역명이 중복 없이 출력된다.
나눈 그룹에 조건 추가
그룹으로 나눠서 집약한 값(count(*))에 대해 조건을 설정하고 싶은 경우
e.g. 센 값이 '각 행정구역에 속한 도시의 수'일 때, 속한 도시의 수가 6개인 행정구역을 선택하고 싶을 때.
WHERE 구문을 사용하면 되지만, 다음 문장은 에러가 발생한다.
select district, count(*) from city where countrycode="KOR" and count(*) = 6 group by district;
ERROR 1111 (HY000): Invalid use of group function
집약한 결과에 조건 지정
select district, count(*) from city where countrycode="KOR" group by district having count(*) = 6;
+---------------+----------+
| district | count(*) |
+---------------+----------+
| Chollabuk | 6 |
| Chungchongnam | 6 |
+---------------+----------+
검색 결과 정렬
SELECT ~ ORDER BY 열1[, 열2, ...];
해당 그룹 내 행정구역 수로 정렬 (오름차순: ASC(default), 내림차순: DESC)
select district, count(name), group_concat(name) from city where countrycode="KOR" group by district order by count(name) desc;
+---------------+-------------+-------------------------------------------------------------------------------------------------------------------------------------+
| district | count(name) | group_concat(name) |
+---------------+-------------+-------------------------------------------------------------------------------------------------------------------------------------+
| Kyonggi | 18 | Kuri,Ichon,Kwangmyong,Pyongtaek,Paju,Yong-in,Ansan,Koyang,Anyang,Shihung,Hanam,Kunpo,Uijongbu,Puchon,Suwon,Uiwang,Namyangju,Songnam |
| Kyongsangnam | 11 | Koje,Chinhae,Kimhae,Miryang,Chang-won,Masan,Chinju,Sachon,Yangsan,Ulsan,Tong-yong |
| Kyongsangbuk | 10 | Yongju,Sangju,Kimchon,Pohang,Kumi,Yongchon,Kyongju,Mun-gyong,Andong,Kyongsan |
| Chollabuk | 6 | Kunsan,Iksan,Namwon,Kimje,Chonju,Chong-up |
| Chungchongnam | 6 | Chonan,Sosan,Kongju,Nonsan,Asan,Poryong |
| Chollanam | 5 | Mokpo,Sunchon,Yosu,Naju,Kwang-yang |
| Kang-won | 4 | Chunchon,Kangnung,Wonju,Tonghae |
| Chungchongbuk | 3 | Chungju,Chongju,Chechon |
| Cheju | 1 | Cheju |
| Inchon | 1 | Inchon |
| Kwangju | 1 | Kwangju |
| Pusan | 1 | Pusan |
| Seoul | 1 | Seoul |
| Taegu | 1 | Taegu |
| Taejon | 1 | Taejon |
+---------------+-------------+-------------------------------------------------------------------------------------------------------------------------------------+
select district, count(name), group_concat(name) from city where countrycode="KOR" group by district having count(name) <= 6 order by count(name) desc;
+---------------+-------------+-------------------------------------------+
| district | count(name) | group_concat(name) |
+---------------+-------------+-------------------------------------------+
| Chollabuk | 6 | Kunsan,Iksan,Namwon,Kimje,Chonju,Chong-up |
| Chungchongnam | 6 | Chonan,Sosan,Kongju,Nonsan,Asan,Poryong |
| Chollanam | 5 | Mokpo,Sunchon,Yosu,Naju,Kwang-yang |
| Kang-won | 4 | Chunchon,Kangnung,Wonju,Tonghae |
| Chungchongbuk | 3 | Chungju,Chongju,Chechon |
| Cheju | 1 | Cheju |
| Inchon | 1 | Inchon |
| Kwangju | 1 | Kwangju |
| Pusan | 1 | Pusan |
| Seoul | 1 | Seoul |
| Taegu | 1 | Taegu |
| Taejon | 1 | Taejon |
+---------------+-------------+-------------------------------------------+
정렬 시 유의할 점
이전 글에서 오름차순(ASC), 내림차순(DESC) 정렬을 이용해 봤는데, 정렬 시 유의할 점이 있다.
ORDER BY에 의한 정렬을 수행할 때 행의 순서를 늘 같게 하려면, 정렬 키를 한 가지로(Unique 하게) 정해야 한다. 즉, 정렬 키가 같은 값의 행이 복수개 존재한다면, 그 행들의 순서는 매번 일정하지 않다.
select * from city where countrycode="KOR" order by district;
+------+------------+-------------+---------------+------------+
| ID | Name | CountryCode | District | Population |
+------+------------+-------------+---------------+------------+
| 2357 | Kunsan | KOR | Chollabuk | 266569 |
| 2352 | Iksan | KOR | Chollabuk | 322685 |
| 2398 | Namwon | KOR | Chollabuk | 103544 |
| 2393 | Kimje | KOR | Chollabuk | 115427 |
| 2342 | Chonju | KOR | Chollabuk | 563153 |
| 2380 | Chong-up | KOR | Chollabuk | 139111 |
| 2361 | Mokpo | KOR | Chollanam | 247452 |
| 2360 | Sunchon | KOR | Chollanam | 249263 |
| 2370 | Yosu | KOR | Chollanam | 183596 |
| 2397 | Naju | KOR | Chollanam | 107831 |
| 2390 | Kwang-yang | KOR | Chollanam | 122052 |
위 예시처럼 같은 정렬 키(district)가 복수개 존재한다면 그 행들의 순서는 일정하지 않을 수 있다.
따라서 위 행들을 일정한 순서로 나열하기 위해서는 unique 한 정렬 키를 지정해야 한다.
order by district, name;
(사실, district만 정렬 키로 사용한 결과도 매 실행마다 같았다.)
종합하면 'ORDER BY, GROUP BY, HAVING'의 작성 순서는 다음과 같다.
SELECT ~ FROM ~ WHERE ~ GROUP BY ~ HAVING ~ ORDER BY ~