
# 聚合操作
GROUP BY子句是SQL中用于数据分组和汇总的核心功能。它的主要目的是将具有相同值的一个或多个列的行组合（分组） 在一起，然后对每个组应用聚合函数（如 SUM(), COUNT(), AVG(), MAX(), MIN()）来计算汇总信息。
#### 按列GROUP BY
- **功能描述**
  按列进行分组操作。
  
- **语法格式**
  ```
  SELECT [ ALL | DISTINCT ]   { * | projectItem [, projectItem ]* }
    FROM tableExpression
    [ WHERE booleanExpression ]
    [ GROUP BY { groupItem [, groupItem ]* } ]
  ```
  
- **语法说明**
  GROUP BY：按列可分为单列GROUP BY与多列GROUP BY。
  - 单列GROUP BY：指GROUP BY子句中仅包含一列。
  
  - 多列GROUP BY：指GROUP BY子句中不止一列，查询语句将按照GROUP BY的所有字段分组，所有字段都相同的记录将被放在同一组中。
   
- **注意事项**
  GroupBy在流处理表中会产生更新结果。
  
- **示例**
  根据score及name两个字段对表student进行分组，并返回分组结果。
  ```
  SELECT name,score, max(score) FROM student 
    GROUP BY name,score;
  ```
  
 
#### 表达式GROUP BY
- **功能描述**
  按表达式对流进行分组操作。
  
- **语法格式**
  ```
  SELECT [ ALL | DISTINCT ]   { * | projectItem [, projectItem ]* }
    FROM tableExpression
    [ WHERE booleanExpression ]
    [ GROUP BY { groupItem [, groupItem ]* } ]
  ```
  
- **语法说明**
  groupItem：可以是单字段，多字段，也可以是字符串函数等调用，不能是聚合函数。
  
- **注意事项**
  无。
  
- **示例**
  先利用substring函数取字段name的子字符串，并按照该子字符串进行分组，返回每个子字符串及对应的记录数。
  ```
  SELECT substring(name,6),count(name) FROM student
    GROUP BY substring(name,6);
  ```
  
 
#### GROUP BY中使用HAVING过滤
- **功能描述**
  利用HAVING子句在表分组后实现过滤。
  
- **语法格式**
  ```
  SELECT [ ALL | DISTINCT ]   { * | projectItem [, projectItem ]* }
    FROM tableExpression
    [ WHERE booleanExpression ]
    [ GROUP BY { groupItem [, groupItem ]* } ]
    [ HAVING booleanExpression ]
  ```
  
- **语法说明**
  HAVING：一般与GROUP BY合用，先通过GROUP BY进行分组，再在HAVING子句中进行过滤。
  
- **注意事项**
  - 如果过滤条件受GROUP BY的查询结果影响，则不能用WHERE子句进行过滤，而要用HAVING子句进行过滤。HAVING与GROUP BY合用，先通过GROUP BY进行分组，再在HAVING子句中进行过滤。
  
  - HAVING中除聚合函数外所使用的字段必须是GROUP BY中出现的字段。
  
  - HAVING子句支持算术运算，聚合函数等。
   
- **示例**
  先依据num对表transactions进行分组，再利用HAVING子句对查询结果进行过滤，price与amount乘积的最大值大于5000的记录将被筛选出来，返回对应的num及price与amount乘积的最大值。
  ```
  SELECT num, max(price*amount) FROM transactions
    WHERE time > '2016-06-01'
    GROUP BY num
    HAVING max(price*amount)>5000;
  ```
  
 
