VillageSQL is a drop-in replacement for MySQL with extensions.
All examples on this page work on VillageSQL. Install Now →
GROUP BY가 없는 집계 함수는 테이블 전체를 1개의 그룹으로 취급하고 1개의 행을 반환합니다. GROUP BY는 행을 먼저 그룹으로 나누므로, 그룹마다 1개의 행을 얻습니다. “영화가 몇 편인가”가 “등급마다 영화가 몇 편인가”가 되는 방법입니다.
시작하기 전에 mysql -u root -p sakila로 클라이언트를 여세요.
GROUP BY의 동작 방식
GROUPING_COLUMN을 값이 그룹을 정의하는 열로, TABLE_NAME을 테이블로, AGGREGATE_FUNCTION(COLUMN_NAME)을 각 그룹에 대해 계산하고 싶은 것으로 바꾸세요.
서버는 행을 그룹화 열의 서로 다른 값마다 1개씩의 바구니로 분류하고, 각 바구니에 대해 따로 집계를 실행합니다. 결과는 서로 다른 값의 수만큼의 행을 가집니다.
GROUP BY는 WHERE 뒤, ORDER BY 앞에 오며, 이것은 결과가 정의되는 순서이기도 합니다: 행을 필터링하고, 살아남은 것을 그룹화한 다음, 그룹을 정렬합니다.
예제
- 값마다 한 행
rating에 5개의 서로 다른 값이 있으므로 5개의 그룹이고, 5개의 개수를 더하면 1,000이 됩니다. 행은 알파벳순이 아니라 ENUM의 선언 순서로 나오며, SELECT DISTINCT 레슨이 그것을 설명합니다.
- 2개의 열로 그룹화
2개의 열을 지정하면, 그룹은 각 열의 값이 아니라 서로 다른 짝입니다.
SELECT DISTINCT rating, rental_rate가 반환하는 것과 같은 형태에, 각 행에 개수가 붙은 것입니다.
- 그룹화 전에 행 필터링하기
WHERE가 먼저 실행되므로, 개수는 그것을 통과한 행에 대한 것입니다.
WHERE가 그 그룹의 행을 모두 제거할 때만 완전히 사라집니다.
- 계산한 것으로 그룹화
그룹화 열이 반드시 열일 필요는 없습니다. 어떤 표현식이든 되고, 별칭으로 이름을 붙여 그것으로 그룹화할 수 있습니다.
GROUP BY는 select 목록의 별칭을 받아들이지만, WHERE는 그렇지 않습니다. 보고서가 월별로 그룹화되는 방법이 이것입니다: 월을 계산하고, 그것으로 그룹화합니다.
- 조인 위에서 그룹화
그룹화는 행이 2개 이상의 테이블에서 올 때 가장 유용합니다. 이 쿼리는 각 고객의 결제를 셉니다.
last_name과 함께 customer_id도 GROUP BY에 있는데, 2명의 고객이 같은 성을 가질 수 있고 그들을 따로 세고 싶기 때문입니다.
선택한 모든 열은 그룹화되거나 집계되어야 합니다
그룹은 많은 행입니다. 그룹화 열도 아니고 집계 함수 안에도 없는 열을 요청하는 것은 그 많은 행 중 어느 것을 보여 줄지 서버에 묻는 것이고, 서버에는 답이 없습니다. 기본적으로 켜져 있는only_full_group_by 설정이 서버가 추측하는 대신 그렇다고 말하게 만드는 것입니다.
ERROR 1055는 해결할 수 없었던 열의 이름을 말해 주는데, 여기서는 title입니다. 빠져나가는 방법은 3가지이고, 어느 것이 맞는지는 의도에 따라 다릅니다:
- 더 세밀한 그룹을 원했다면, 그 열을
GROUP BY에 추가하세요. - 아무 값 1개면 된다면,
MIN(title)같은 집계 함수로 감싸세요. - 필요 없었다면, select 목록에서 빼세요.
only_full_group_by를 끄면 같은 쿼리가 실행되고, 서버가 고른 플랜에 따라 임의의 제목을 반환합니다. MySQL GROUP BY 성능 가이드가 그 설정과, 일부러 임의의 행을 요청하는 방법인 ANY_VALUE()를 다룹니다.
GROUP BY는 순서를 약속하지 않습니다
그룹은 서버가 편리하다고 본 순서로 돌아옵니다. 여기의 모든 예제가ORDER BY를 쓰는 것은 그것이 순서를 고정하는 유일한 방법이기 때문이며, LIMIT에서와 같습니다.
요약
- 전체 1개 대신 서로 다른 값마다 1개의 결과 행을 얻으려면
GROUP BY를 사용하세요. - 여러 열을 지정하면 서로 다른 조합마다 그룹이 생긴다고 예상하세요.
WHERE가 그룹화가 일어나기 전에 행을 필터링한다고 예상하세요.ERROR 1055는 그룹화되지도 집계되지도 않은 열로 읽으세요.- 그룹의 순서가 중요하면
ORDER BY를 추가하세요.
함께 보기
- 집계 함수 — 그룹마다 계산할 것
- HAVING — 그룹이 만들어진 뒤에 그룹 필터링하기
- WITH ROLLUP — 그룹 아래에 합계 행 추가하기
- MySQL GROUP BY 성능 — 이것이 만들 수 있는 임시 테이블