SELECT =========================== SELECT 的语法相对比较复杂。本节首先会介绍普通的 SELECT 语法结构,然后介绍集合类 SELECT 的语法结构。 SIMPLE SELECT ---------------------- ### 描述 该语句用于查询表中的内容。 ### 格式 ```javascript simple_select: SELECT [/*+ hint statement */] [ALL | DISTINCT | UNIQUE | SQL_CALC_FOUND_ROWS] select_expr_list FROM from_list [WHERE condition] [GROUP BY group_expression_list [WITH ROLLUP] [HAVING condition]] [ORDER BY order_expression_list] [limit_clause] [FOR UPDATE] select_expr: table_name.* | table_alias_name.* | expr [[AS] column_alias_name] from_list: table_reference [, table_reference ...] table_reference: simple_table | joined_table simple_table: table_factor [partition_option] [[AS] table_alias_name] | (select_stmt) [AS] table_alias_name | (table_reference_list) joined_table: table_reference [INNER] JOIN simple_table [join_condition] | table_reference outer_join_type JOIN simple_table join_condition partition_option: PARTITION (partition_name_list) partition_name_list: partition_name [, partition_name ...] outer_join_type: {LEFT | RIGHT | FULL} [OUTER] join_condition: ON expression condition: expression group_expression_list: group_expression [, group_expression ...] group_expression: expression [ASC | DESC] order_expression_list: order_expression [, order_expression ...] order_expression: expression [ASC | DESC] limit_clause: LIMIT {[offset,] row_count |row_count OFFSET offset} ``` ### 参数解释 | 参数 | 描述 | |--------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | ALL \| DISTINCT \| UNIQUE \| SQL_CALC_FOUND_ROWS | 在数据库表中,可能会包含重复值。 * 指定"DISTINCT",则在查询结果中相同的行只显示一行; * 指定"ALL",则列出所有的行; * 指定"SQL_CALC_FOUND_ROWS",则不输出数据,只返回数据行数; * 不指定时,默认为"ALL"。 | | select_expr | 列出要查询的表达式或列名,用","隔开。也可以用"\*"表示所有列。 | | AS othername | 为输出字段重新命名。 | | FROM table_references | 指名了从哪个表或哪些表中读取数据(支持多表查询)。 | | WHERE where_conditions | 可选项,WHERE 字句用来设置一个筛选条件,查询结果中仅包含满足条件的数据。where_conditions 为表达式。 | | GROUP BY group_by_list | 用于进行分类汇总。 | | HAVING search_confitions | HAVING 字句与 WHERE 字句类似,但是 HAVING 字句可以使用累计函数(如 SUM,AVG 等)。 | | ORDER BY order_list order_list : colname \[ASC \| DESC\] \[,colname \[ASC \| DESC\]...\] | 用来按升序(ASC)或者降序(DESC)显示查询结果。不指定 ASC 或者 DESC 时,默认为 ASC。 | | \[LIMIT {\[offset,\] row_count \|row_count OFFSET offset}\] | 强制 SELECT 语句返回指定的记录数。 LIMIT 接受一个或两个数字参数。参数必须是一个整数常量。 * 如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。初始记录行的偏移量是 0(而不是 1)。 * 如果只给定一个参数,它表示返回记录行的最大数目,偏移量为0。 | | FOR UPDATE | 对查询结果所有行上排他锁,以阻止其他事务的并发修改,或阻止在某些事务隔离级别时的并发读取。 | | PARTITION(partition_list) | 指定查询表的分区信息。例如:partition(p0,p1...) | ### 示例 以如下表 a 为例。 ![image.png](https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/5455055061/p179248.png "image.png") * 从表 a 中读取 name 数据。 ```javascript SELECT name FROM a; ``` ![image.png](https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/5455055061/p179249.png "image.png") * 在查询结果中对 name 进行去重处理。 ```javascript SELECT DISTINCT name FROM a; ``` ![image.png](https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/5455055061/p179250.png "image.png") * 从表 a 中查询 id,name,num,然后把 num 列除以2输出,输出的列名为 avg。 ```javascript SELECT id, name, num/2 AS avg FROM a; ``` ![image.png](https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/5455055061/p179251.png "image.png") * 从表 a 中根据筛选条件" name = 'a' " ,输出对应的 id 、name 和 num 。 ```javascript SELECT id, name, num FROM a WHERE name = 'a'; ``` ![image.png](https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/5455055061/p179252.png "image.png") * 从表 a 中查询 id,name,按照 name 分组对 num 求和,并输出。 ```javascript SELECT id, name, SUM(num) FROM a GROUP BY name; ``` ![image.png](https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/6455055061/p179253.png "image.png") * 从表 a 中查询 id,name,按照 name 分组对 num 求和,查询 num 总和小于160的行,并输出。 ```javascript SELECT id, name, SUM(num) as sum FROM a GROUP BY name HAVING SUM(num) < 160; ``` ![image.png](https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/6455055061/p179254.png "image.png") * 从表 a 中查询 id,name,num,根据 num 按升序(ASC)输出查询结果。 ```javascript SELECT * FROM a ORDER BY num ASC; ``` ![image.png](https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/6455055061/p179255.png "image.png") * 从表 a 中查询 id,name,num,根据 num 按降序(DESC)输出查询结果。 ```javascript SELECT * FROM a ORDER BY num DESC; ``` ![](https://icms.alibaba-inc.com/api/v2/open/lite-inoe/cms/load?url=../images/p179256.png&langId=1&t=1604912832327) * 从表 a 中查询 id,name,num,使用 LIMIT强制从第2行开始,返回表 a 的两行结果。 ```javascript SELECT * FROM a LIMIT 1,2; ``` ​![](https://cdn.nlark.com/yuque/0/2020/png/1701278/1595841219661-e9f4c4ae-ec93-4828-be06-1d5f9004e788.png) 集合类 SELECT ------------------- ### 描述 该语句用于对多个 SELECT 查询的结果进行 UNION,MINUS,INTERSECT。 ### 格式 ```javascript select_clause_set: simple_select [ UNION | UNION ALL | EXCEPT | INTERSECT] select_clause_set_left [ORDER BY sort_list_columns] [limit_clause] select_clause_set_right: simple_select | select_caluse_set ``` ### 参数解释 | 参数 | 描述 | |-----------|--------------------------| | UNION ALL | 合并两个查询的结果 | | UNION | 合并两个查询的结果,并去重 | | EXCEPT | 从左查询结果集中去重出现在右查询中的结果,并去重 | | INTERSECT | 保留左查询结果集中出现在右查询中的结果,并去重 | ### 示例 以如下两表的数据为例: ```javascript create table t1 (c1 int, c2 int); create table t2 (c1 int, c2 int); insert into t1 values (1, -1), (2, -2); insert into t2 values (1, 1), (2, -2), (3, 3); ``` * 计算 T1, T2 的所有的记录 ```javascript SELECT C1, C2 FROM T1 UNION ALL SELECT C1, C2 FROM T2; +------+------+ | C1 | C2 | +------+------+ | 1 | -1 | | 2 | -2 | | 1 | 1 | | 2 | -2 | | 3 | 3 | +------+------+ ``` * 计算 T1, T2 的去重后的所有记录 ```javascript SELECT C1, C2 FROM T1 UNION SELECT C1, C2 FROM T2; +------+------+ | C1 | C2 | +------+------+ | 1 | -1 | | 2 | -2 | | 1 | 1 | | 3 | 3 | +------+------+ ``` * 计算 T1 和 T2 的交集 ```javascript SELECT C1, C2 FROM T1 INTERSECT SELECT C1, C2 FROM T2; +------+------+ | C1 | C2 | +------+------+ | 2 | -2 | +------+------+ ``` * 计算 T1 和 T2 的差集 ```javascript SELECT C1, C2 FROM T1 EXCEPT SELECT C1, C2 FROM T2; +------+------+ | C1 | C2 | +------+------+ | 1 | -1 | +------+------+ ``` * 取 T1 和 T2 并集中 C2 排序最大的前两行 ```javascript SELECT C1, C2 FROM T1 UNION SELECT C1, C2 FROM T2 ORDER BY C2 DESC LIMIT 2; +------+------+ | C1 | C2 | +------+------+ | 3 | 3 | | 1 | 1 | +------+------+ ```