
# SELECT
#### SELECT
**语法格式**
```
SELECT [ ALL | DISTINCT ]
  { * | projectItem [, projectItem ]* }
  FROM tableExpression
  [ WHERE booleanExpression ]
  [ GROUP BY { groupItem [, groupItem ]* } ]
  [ HAVING booleanExpression ]
```
**语法说明**
SELECT语句用于从表中选取数据。
ALL表示返回所有结果。
DISTINCT表示返回不重复结果。
**注意事项**
- 所查询的表必须是已经存在的表，否则会出错。
- WHERE关键字指定查询的过滤条件，过滤条件中支持算术运算符，关系运算符，逻辑运算符。
- GROUP BY指定分组的字段，可以单字段分组，也可以多字段分组。
**示例**
找出数量超过3的订单。
```
insert into temp SELECT  * FROM Orders WHERE units > 3;
```
插入一组常量数据。
```
insert into temp select 'Lily’, ‘male’, ‘student’, 17;
```
#### WHERE过滤子句
**语法格式**
```
SELECT   { * | projectItem [, projectItem ]* }
  FROM tableExpression
  [ WHERE booleanExpression ]
```
**语法说明**
利用WHERE子句过滤查询结果。
**注意事项**
- 所查询的表必须是已经存在的，否则会出错。
- WHERE条件过滤，将不满足条件的记录过滤掉，返回满足要求的记录。
**示例**
找出数量超过3并且小于10的订单。
```
insert into temp SELECT  * FROM Orders
  WHERE units > 3 and units < 10;
```
#### HAVING过滤子句
**功能描述**
利用HAVING子句过滤查询结果。
**语法格式**
```
SELECT [ ALL | DISTINCT ]   { * | projectItem [, projectItem ]* }
  FROM tableExpression
  [ WHERE booleanExpression ]
  [ GROUP BY { groupItem [, groupItem ]* } ]
  [ HAVING booleanExpression ]
```
**语法说明**
HAVING：一般与GROUP BY合用，先通过GROUP BY进行分组，再在HAVING子句中进行过滤，HAVING子句支持算术运算，聚合函数等。
**注意事项**
如果过滤条件受GROUP BY的查询结果影响，则不能用WHERE子句进行过滤，而要用HAVING子句进行过滤。
**示例**
根据字段name对表student进行分组，再按组将score最大值大于95的记录筛选出来。
```
insert into temp SELECT name, max(score) FROM student
  GROUP BY name
  HAVING max(score) >95;
```
#### 按列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进行分组，并返回分组结果。
```
insert into temp 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的子字符串，并按照该子字符串进行分组，返回每个子字符串及对应的记录数。
```
insert into temp SELECT substring(name,6),count(name) FROM student
  GROUP BY substring(name,6);
```
#### Grouping sets, Rollup, Cube
**功能描述**
- GROUPING SETS 的 GROUP BY 子句可以生成一个等效于由多个简单 GROUP BY 子句的 UNION ALL 生成的结果集，并且其效率比 GROUP BY 要高。
- ROLLUP与CUBE按一定的规则产生多种分组，然后按各种分组统计数据。
- CUBE生成的结果集显示了所选列中值的所有组合的聚合。
- Rollup生成的结果集显示了所选列中值的某一层次结构的聚合。
**语法格式**
```
SELECT [ ALL | DISTINCT ]   { * | projectItem [, projectItem ]* }
  FROM tableExpression
  [ WHERE booleanExpression ]
  [ GROUP BY groupingItem]
```
**语法说明**
groupingItem：是Grouping sets(columnName \[, columnName\]\*)、Rollup(columnName \[, columnName\]\*)、Cube(columnName \[, columnName\]\*)
**注意事项**
无
**示例**
分别产生基于user和product的结果
```
INSERT INTO temp SELECT SUM(amount)
FROM Orders
GROUP BY GROUPING SETS ((user), (product));
```
#### 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乘积的最大值。
```
insert into temp SELECT num, max(price*amount) FROM transactions
  WHERE time > '2016-06-01'
  GROUP BY num
  HAVING max(price*amount)>5000;
```
