메인 콘텐츠로 건너뛰기

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 앞에 오며, 이것은 결과가 정의되는 순서이기도 합니다: 행을 필터링하고, 살아남은 것을 그룹화한 다음, 그룹을 정렬합니다.

예제

  1. 값마다 한 행

rating에 5개의 서로 다른 값이 있으므로 5개의 그룹이고, 5개의 개수를 더하면 1,000이 됩니다. 행은 알파벳순이 아니라 ENUM의 선언 순서로 나오며, SELECT DISTINCT 레슨이 그것을 설명합니다.

  1. 2개의 열로 그룹화

2개의 열을 지정하면, 그룹은 각 열의 값이 아니라 서로 다른 짝입니다.
5개의 등급 곱하기 3개의 요금은 15개의 그룹입니다. 이것은 SELECT DISTINCT rating, rental_rate가 반환하는 것과 같은 형태에, 각 행에 개수가 붙은 것입니다.

  1. 그룹화 전에 행 필터링하기

WHERE가 먼저 실행되므로, 개수는 그것을 통과한 행에 대한 것입니다.
여전히 5개의 그룹이고, 모두 더 작아졌습니다. 그룹은 WHERE가 그 그룹의 행을 모두 제거할 때만 완전히 사라집니다.

  1. 계산한 것으로 그룹화

그룹화 열이 반드시 열일 필요는 없습니다. 어떤 표현식이든 되고, 별칭으로 이름을 붙여 그것으로 그룹화할 수 있습니다.
GROUP BY는 select 목록의 별칭을 받아들이지만, WHERE는 그렇지 않습니다. 보고서가 월별로 그룹화되는 방법이 이것입니다: 월을 계산하고, 그것으로 그룹화합니다.

  1. 조인 위에서 그룹화

그룹화는 행이 2개 이상의 테이블에서 올 때 가장 유용합니다. 이 쿼리는 각 고객의 결제를 셉니다.
조인이 먼저 실행되어 결제마다 1개의 행을 만들고, 그다음 그룹화가 그 행들을 고객별로 합칩니다. 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를 추가하세요.

함께 보기