카테고리:

쿼리 구문

GROUP BY

항목별로 그룹화하는 동일한 식으로 행을 그룹화하고, 결과 그룹에 대한 집계 함수를 계산합니다. GROUP BY 식은 다음과 같을 수 있습니다.

  • 열 이름.

  • SELECT 목록에서 위치를 참조하는 숫자.

  • 일반적인 식입니다.

확장:

GROUP BY CUBE , GROUP BY GROUPING SETS , GROUP BY ROLLUP

구문

SELECT ...
  FROM ...
  [ ... ]
  GROUP BY groupItem [ , groupItem [ , ... ] ]
  [ ... ]
Copy
SELECT ...
  FROM ...
  [ ... ]
  GROUP BY ALL
  [ ... ]
Copy

여기서

groupItem ::= { <column_alias> | <position> | <expr> }
Copy

매개 변수

column_alias

쿼리 블록의 SELECT 목록에 나타나는 열 별칭입니다.

position

SELECT 목록에서 식의 위치입니다.

expr

현재 범위의 테이블에 대한 모든 식입니다.

GROUP BY ALL

집계 함수를 사용하지 않는 SELECT 목록의 모든 항목을 그룹화에 사용해야 함을 지정합니다.

예는 모든 열로 그룹화 섹션을 참조하십시오.

사용법 노트

  • GROUP BY 절은 이름 또는 위치별로 프로젝션 절의 식을 참조할 수 있습니다. GROUP BY 절이 이름으로 참조하는 경우 각 참조는 다음과 같이 확인됩니다.

    • 쿼리에 열 이름이 일치하는 데이터베이스 오브젝트(예: 테이블 또는 뷰)가 포함되어 있으면 참조가 열 이름으로 확인됩니다.

    • 그렇지 않고 SELECT의 프로젝션 절에 이름이 일치하는 식 별칭이 포함되어 있으면 참조는 별칭으로 확인됩니다.

    예를 보려면 Precedence when a column name and an alias match 를 참조하십시오.

  • 모든 SELECT 항목이 집계 함수를 사용하는 경우 GROUP BY ALL을 지정하는 것은 GROUP BY 절 없이 문을 지정하는 것과 같습니다.

    예를 들어, 다음 문에는 집계 함수를 사용하는 SELECT 항목만 있습니다.

    SELECT SUM(amount)
      FROM mytable
      GROUP BY ALL;
    
    Copy

    위의 문은 GROUP by 절을 지정하지 않는 것과 같습니다.

    SELECT SUM(amount)
      FROM mytable;
    
    Copy

다음 섹션에서는 GROUP BY 절을 사용하는 예를 제시합니다.

각 섹션의 예에서는 예제를 위한 데이터 설정하기 에서 설정한 데이터를 사용합니다.

예제를 위한 데이터 설정하기

이 섹션의 예에서는 sales 라는 테이블과 product 라는 테이블을 사용합니다. 이러한 테이블을 만들고 예제에 필요한 데이터를 삽입하려면 다음 문을 실행하십시오.

CREATE TABLE sales (
  product_ID INTEGER,
  retail_price REAL,
  quantity INTEGER,
  city VARCHAR,
  state VARCHAR);

INSERT INTO sales (product_id, retail_price, quantity, city, state) VALUES
  (1, 2.00,  1, 'SF', 'CA'),
  (1, 2.00,  2, 'SJ', 'CA'),
  (2, 5.00,  4, 'SF', 'CA'),
  (2, 5.00,  8, 'SJ', 'CA'),
  (2, 5.00, 16, 'Miami', 'FL'),
  (2, 5.00, 32, 'Orlando', 'FL'),
  (2, 5.00, 64, 'SJ', 'PR');

CREATE TABLE products (
  product_ID INTEGER,
  wholesale_price REAL);
INSERT INTO products (product_ID, wholesale_price) VALUES (1, 1.00);
INSERT INTO products (product_ID, wholesale_price) VALUES (2, 2.00);
Copy

한 열로 그룹화

이 예에서는 product_id 로 그룹화된 제품당 총매출을 보여줍니다(즉, 각 제품에 대해 받은 총액).

SELECT product_ID, SUM(retail_price * quantity) AS gross_revenue
  FROM sales
  GROUP BY product_ID;
Copy
+------------+---------------+
| PRODUCT_ID | GROSS_REVENUE |
+============+===============+
|          1 |          6    |
+------------+---------------+
|          2 |        620    |
+------------+---------------+

다음 예에서는 이전 예를 기반으로 하여 product_id 기준으로 그룹화된 제품당 순이익을 보여줍니다.

SELECT p.product_ID, SUM((s.retail_price - p.wholesale_price) * s.quantity) AS profit
  FROM products AS p, sales AS s
  WHERE s.product_ID = p.product_ID
  GROUP BY p.product_ID;
Copy
+------------+--------+
| PRODUCT_ID | PROFIT |
+============+========+
|          1 |      3 |
+------------+--------+
|          2 |    372 |
+------------+--------+

여러 열로 그룹화

다음 예에서는 여러 열을 기준으로 그룹화하는 방법을 보여줍니다.

SELECT state, city, SUM(retail_price * quantity) AS gross_revenue
  FROM sales
  GROUP BY state, city;
Copy
+-------+---------+---------------+
| STATE |   CITY  | GROSS REVENUE |
+=======+=========+===============+
|   CA  | SF      |            22 |
+-------+---------+---------------+
|   CA  | SJ      |            44 |
+-------+---------+---------------+
|   FL  | Miami   |            80 |
+-------+---------+---------------+
|   FL  | Orlando |           160 |
+-------+---------+---------------+
|   PR  | SJ      |           320 |
+-------+---------+---------------+

모든 열로 그룹화

다음 예제는 여러 열로 그룹화 에서 사용된 예제와 동일합니다.

SELECT state, city, SUM(retail_price * quantity) AS gross_revenue
  FROM sales
  GROUP BY ALL;
Copy
+-------+---------+---------------+
| STATE |   CITY  | GROSS REVENUE |
+=======+=========+===============+
|   CA  | SF      |            22 |
+-------+---------+---------------+
|   CA  | SJ      |            44 |
+-------+---------+---------------+
|   FL  | Miami   |            80 |
+-------+---------+---------------+
|   FL  | Orlando |           160 |
+-------+---------+---------------+
|   PR  | SJ      |           320 |
+-------+---------+---------------+

Precedence when a column name and an alias match

It is possible (but usually not recommended) to create a query that contains an alias that matches a column name:

SELECT x, some_expression AS x
  FROM ...
Copy

If a clause contains a name that matches both a column name and an alias, then the clause uses the column name. The following example demonstrates this behavior using a GROUP BY clause:

테이블을 만들고 행을 삽입합니다.

CREATE TABLE employees (salary FLOAT, state VARCHAR, employment_state VARCHAR);
INSERT INTO employees (salary, state, employment_state) VALUES
  (60000, 'California', 'Active'),
  (70000, 'California', 'On leave'),
  (80000, 'Oregon', 'Active');
Copy

The following query returns the sum of the salaries of the employees who are active and the sum of the salaries of the employees who are on leave:

SELECT SUM(salary), ANY_VALUE(employment_state)
  FROM employees
  GROUP BY employment_state;
Copy
+-------------+-----------------------------+
| SUM(SALARY) | ANY_VALUE(EMPLOYMENT_STATE) |
|-------------+-----------------------------|
|      140000 | Active                      |
|       70000 | On leave                    |
+-------------+-----------------------------+

The next query uses the alias state, which matches the name of a column of the table in the query. When state is used in the GROUP BY clause, Snowflake interprets it as a reference to the column name, not the alias. This query therefore returns the sum of the salaries of the employees in the state of California and the sum of the salaries of the employees in the state of Oregon, yet displays employment_state information (that is, Active) rather than the names of states or provinces.

SELECT SUM(salary), ANY_VALUE(employment_state) AS state
  FROM employees
  GROUP BY state;
Copy
+-------------+--------+
| SUM(SALARY) | STATE  |
|-------------+--------|
|      130000 | Active |
|       80000 | Active |
+-------------+--------+