标准语法:

SELECT语法的总体结构:

[ WITH with_subquery_table_name AS ( query ) ]
SELECT
[DISTINCT] select_expr [, select_expr ...]
[FROM  table_reference [, ...] ]
[WHERE filter_condition]
[GROUP BY { expr | ROLLUP ( expr_list ) | CUBE ( expr_list ) | GROUPING SETS ( expr_list )} , ...]
[HAVING having_condition]
[ORDER BY {col_name | expr }
[ASC | DESC], ...]
[{ UNION [ ALL ] | INTERSECT | EXCEPT } (SELECT select_expr..)]
[LIMIT {row_count}]

WITH子句

WITH语句用于定义一个或者多个子查询,每个子查询定义一个临时表,类似于视图的定义; 在WITH中定义的临时表可以在当前查询的其他子句中引用;所有的WITH语句定义的临时表,都可以通过SELECT子句中的子查询定义来完成类似的效果,但是当这些子查询或者临时表被后面的字句多次引用时,WITH语句只需要计算一次临时表结果,然后多次复用,从而达到减少公共表达式计算的次数。

语法:

[ WITH with_subquery [, ...] ]

而 with_subquery的语法为:

with_subquery_table_name AS ( query )

参数:

  • with_subquery_table_name:当前查询中一个唯一的临时表名称
  • query:所有可以支持的SELECT查询

例如:

with t as (select x,y from A) select t.y from t order by t.x limit 10

SELECT列表

SELECT语句中的列投影的基本结构为:

SELECT [ ALL | DISTINCT ] * | expression [ AS column_alias ] [, ...]

参数:

  • ALL:当不需要定义DISTINCT时的一个可选冗余字段。
  • DISTINCT:用于消除重复的行。
  • *:返回所有的列。
  • expression:一个或者多个列引用,也可以是带函数的列表达式。
  • AS column_alias:用于定义select列的别名,AS关键字可选。AS后面接的alias如果是一个带空格的字符串,可以使用 ` 符号括起来。

FROM子句

FROM子句的语法为:

FROM table_reference [, ...]

其中 table_reference支持的格式如下:

with_subquery_table_name [ [ AS ] alias ]
table_name [ * ] [ [ AS ] alias ]
( subquery ) [ AS ] alias 
table_reference join_type table_reference
[ ON join_condition ]

参数:

  • with_subquery_table_name:WITH语句定义的子查询名字。
  • table_name:表名或者视图名称。
  • alias:表或者视图的别名。
  • join_type:连接类型,包括[INNER] JOIN、 LEFT [OUTER] JOIN、RIGHT [OUTER] JOIN和CROSS JOIN。
  • join_condition:用于join的on条件,on后面的条件只能是等值关系,非等值关系需在where子句中定义。

WHERE子句

WHERE子句语法为:

[WHERE filter_condition]

其中filter_condition可以是用ANDOR等二元逻辑操作符连接的多个表达式,也可以是INNOT INEXISTNOT EXIST构成的相关或非相关子查询(或Semi Join)。

GROUP BY子句

GROUP BY 用于做分组操作,语法为:

GROUP BY [ROLLUP | CUBE] expression [, ...]

GROUP BY 后的表达式必须是select list中的非聚合表达式。

说明 group by不支持别名,例如: select x+1 as t from table group by t

HAVING子句

Having子句用于做分组后面的过滤,语法为:

[ HAVING condition ]

备注:

  • HAVING 条件引用的表达式必须出现在group by的列中,或者引用聚合列表达式。
  • HAVING 条件不支持select list中列的别名,必须要重写列表达式。
  • HAVING 条件不支持select list中列的下标引用。

ORDER BY子句

ORDER BY子句用于做排序,语法为:

[ ORDER BY expression
[ ASC | DESC ]
[ LIMIT { count | ALL } ]

参数:

  • expression:定义如何排序,可以是select list中的列或者别名,也可以是没有出现在select list中的列。
  • ASC | DESC:定义排序的方式,升序(ASC)或者降序(DESC),NULL值默认排在前面。
  • LIMIT number | ALL:控制返回结果集的行数,number指定行数,ALL等同于返回所有行。

备注:

  • • 支持offset,如LIMIT n, m

UNION / INTERSECT / EXCEPT / MINUS子句

UNION / INTERSECT / EXCEPT / MINUS用于进行集合求并、交、差操作,语法为:

query
{ UNION [ ALL ] | INTERSECT | EXCEPT | MINUS }
query

参数:

  • query:操作符前后的query输出的列数目和类型都必须完全一致。
  • UNION [ALL]:集合求并操作,输出合并后的结果,ALL表示无需去重。
  • INTERSECT:集合求交操作,输出各个query的交集。
  • EXCEPT:集合求差操作,返回query的差集结果。
  • MINUS:集合求差操作,同EXCEPT

集合操作的排序:

UNIONEXCEPT 操作符都是左结合(left-associative),从左至右进行运算,例如:

select * from t1
union
select * from t2
except
select * from t3
order by c1;

相当于先做完t1 union t2 except t3, 最后才是对前面的结果按照c1进行全局排序。

Intersect操作符的优先级是高于 UNIONEXCEPT的, 例如:

select * from t1
union
select * from t2
intersect
select * from t3
order by c1;

等同于:

select * from t1
union
(select * from t2
intersect
select * from t3)
order by c1;

备注:

  • 集合操作符前的query是不可以带order by语句的,如果要带,需要用括号括起来。