首批通过分布式安全可靠测评,为关键业务系统打造
SELECT 语句
更新时间:2026-07-15 20:42:47
SELECT 的语法相对比较复杂。本节首先会介绍普通的 SELECT 语法结构,然后介绍集合类 SELECT 的语法结构。
描述
该语句用于查询表中的内容。
语法
SELECT
[/*+ hint statement */]
[ALL | DISTINCT | UNIQUE | SQL_CALC_FOUND_ROWS]
[HIGH_PRIORITY]
[STRAIGHT_JOIN]
[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
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 [opt_for_update_wait]]
[LOCK IN SHARE MODE];
select_expr:
table_name.*
| table_alias_name.*
| expr [[AS] column_alias_name]
from_list:
DUAL
| table_reference [, table_reference ...]
table_reference:
simple_table
| joined_table
| table_name@dblink_name
simple_table:
table_factor [partition_option]
[sample_clause [opt_seed]]
[[AS] table_alias_name][index_hint]
| (select_stmt [sample_clause [opt_seed])
[AS] table_alias_name [index_hint]
| (table_reference_list) [index_hint]
joined_table:
table_reference [NATURAL][INNER] JOIN simple_table [join_condition]
| table_reference outer_join_type JOIN simple_table join_condition
partition_option:
PARTITION (partition_name_list)
sample_clause:
SAMPLE [BLOCK] [ ALL | BASE | INCR] (sample_percent)
opt_seed:
SEED(integer)
index_hint:
{USE | FORCE | IGNORE} {KEY | INDEX}
[FOR {JOIN | ORDER BY | GROUP BY}] (index_list)
index_list:
index_name [, index_name ...]
partition_name_list:
partition_name [, partition_name ...]
outer_join_type:
[NATURAL]{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}
opt_for_update_wait:
WAIT { DECIMAL | INTNUM }
| NOWAIT | NO_WAIT
| SKIP LOCKED
参数解释
| 参数 | 描述 |
|---|---|
| ALL | DISTINCT | UNIQUE | SQL_CALC_FOUND_ROWS | 在数据库表中,可能会包含重复值。
|
| HIGH_PRIORITY | 可选项,指定该 SELECT 语句比更新表操作更高的优先级。当前版本仅支持该关键字语法,功能不生效。 |
| STRAIGHT_JOIN | 可选项,强制优化器按照 FROM 子句中所列出的顺序连接表。调优命令,不影响执行结果。
注意OceanBase 数据库并不完全兼容 MySQL 中的 |
| SQL_SMALL_RESULT | SQL_BIG_RESULT | 可选项,当使用 GROUP BY 或 DISTINCT 时,可以通过指定 SQL_BIG_RESULT 或 SQL_SMALL_RESULT 来告知优化器结果集的大小。当前版本仅支持该关键字语法,功能不生效。 |
| SQL_BUFFER_RESULT | 可选项,使用 SQL_BUFFER_RESULT 选项会强制将结果集存储到一个临时表中。当前版本仅支持该关键字语法,功能不生效。 |
| select_expr | 列出要查询的表达式或列名,以逗号(,)分隔。也可以用星号(*)表示所有列。 |
| AS othername | 为输出字段重新命名。 |
| FROM table_references | 指明了从哪个表或哪些表中读取数据(支持多表查询)。 |
| WHERE where_conditions | 可选项,WHERE 字句用来设置一个筛选条件,查询结果中仅包含满足条件的数据。where_conditions 为表达式。 |
| GROUP BY group_by_list | 用于进行分类汇总。 |
| WITH ROLLUP | 将各分组进行汇总以表示更高级的聚合(也称为超聚合),并产生额外的行。 |
| HAVING search_confitions | HAVING 字句与 WHERE 字句类似,但是 HAVING 字句可以使用聚合函数(如 SUM,AVG 等)。 |
| SAMPLE [BLOCK] [ ALL | BASE | INCR] (sample_percent) | 只扫描一部分记录。
|
| SEED integer | 采样的种子值,取值范围为 [0,4294967295],相同的采样种子值总会返回相同的结果。 |
| {USE | FORCE | IGNORE} {KEY | INDEX} [FOR {JOIN | ORDER BY | GROUP BY}] (index_list) | 进行查询是否使用指定的索引。
|
| SQL_CALC_FOUND_ROWS | 用来按升序(ASC)或者降序(DESC)显示查询结果。缺省为 ASC。 |
| [LIMIT {[offset,] row_count |row_count OFFSET offset}] | 强制 SELECT 语句返回指定的记录数。 LIMIT 接受一个或两个数字参数。参数必须是一个整数常量。
|
| FOR UPDATE | 对查询结果所有行上排他锁,以阻止其他事务的并发修改,或阻止在某些事务隔离级别时的并发读取。更多锁选项信息,参见 opt_for_update_wait。 |
| PARTITION(partition_list) | 指定查询表的分区信息。例如 partition(p0,p1...)。 |
| dblink_name | 使用 dblink 查询远端数据库表的数据。
说明该内容仅适用于 OceanBase 数据库企业版。OceanBase 数据库社区版暂不支持 |
| LOCK IN SHARE MODE | 锁定查询结果。 |
opt_for_update_wait
WAIT:表示等待其他事务释放资源的时间,如果超过该时间,则返回无法获得资源,单位为秒。NOWAIT或NO_WAIT:表示不会等待其他事务释放资源,直接返回无法获得资源。SKIP LOCKED:表示不会等待获取行锁,查询会立即执行,从结果集中移除被锁定的行。
更多使用 FOR UPDATE 的示例信息,参见 锁定查询结果 SELECT FOR UPDATE。
示例
简单的表查询示例
以如下表 a 为例。

从表
a中读取name数据。obclient> SELECT name FROM a; +------+ | name | +------+ | a | | b | | a | +------+在查询结果中对
name进行去重处理。obclient> SELECT DISTINCT name FROM a; +------+ | name | +------+ | a | | b | +------+从表
a中查询id、name、num,然后把num列除以 2 输出,输出的列名为avg。obclient> SELECT id, name, num/2 AS avg FROM a; +------+------+----------+ | id | name | avg | +------+------+----------+ | 1 | a | 50.0000 | | 2 | b | 100.0000 | | 3 | a | 25.0000 | +------+------+----------+从表
a中根据筛选条件name = 'a',输出对应的id、name和num。obclient> SELECT id, name, num FROM a WHERE name = 'a'; +------+------+------+ | id | name | num | +------+------+------+ | 1 | a | 100 | | 3 | a | 50 | +------+------+------+从表
a中查询id、name,按照name分组对num求和,并输出。obclient> SELECT id, name, SUM(num) FROM a GROUP BY name; +------+------+----------+ | id | name | SUM(num) | +------+------+----------+ | 1 | a | 150 | | 2 | b | 200 | +------+------+----------+从表
a中查询id、name,按照name分组对num求和,查询num总和小于160的行,并输出。obclient> SELECT id, name, SUM(num) as sum FROM a GROUP BY name HAVING SUM(num) < 160; +------+------+------+ | id | name | sum | +------+------+------+ | 1 | a | 150 | +------+------+------+从表
a中查询id、name、num,根据num按升序(ASC)输出查询结果。obclient> SELECT * FROM a ORDER BY num ASC; +------+------+------+ | id | name | num | +------+------+------+ | 3 | a | 50 | | 1 | a | 100 | | 2 | b | 200 | +------+------+------+从表
a中查询id、name、num,根据num按降序(DESC)输出查询结果。obclient> SELECT * FROM a ORDER BY num DESC; +------+------+------+ | id | name | num | +------+------+------+ | 2 | b | 200 | | 1 | a | 100 | | 3 | a | 50 | +------+------+------+从表
a中查询id、name、num,使用LIMIT强制从第 2 行开始,返回表a的两行结果。obclient> SELECT * FROM a LIMIT 1,2; +------+------+------+ | id | name | num | +------+------+------+ | 2 | b | 200 | | 3 | a | 50 | +------+------+------+可以通过
SELECT ... FOR UPDATE为表加行级锁。如果使用了LIMIT 1子句,则会在查询优化中将算子下压到表扫描的步骤中,只为LIMIT返回的行加锁。obclient> SELECT * FROM a LIMIT 1 FOR UPDATE;如果您使用了
ORDER BY子句对查询结果进行排序,则会先对结果进行排序,然后再执行LIMIT 1,因此这种情况下,会为选择的所有行加锁。obclient> SELECT * FROM a ORDER BY id LIMIT 1 FOR UPDATE;使用
LOCK IN SHARE MODE锁定对表a的查询结果。obclient> SELECT * FROM a LOCK IN SHARE MODE; +------+------+------+ | id | name | num | +------+------+------+ | 1 | a | 100 | | 2 | b | 200 | | 3 | a | 50 | +------+------+------+ 3 row in set
使用 dblink 查询数据的示例
读取远端
test库中的number_t表obclient> SELECT * FROM number_t@ob_dblink; +--------+-------------+---------+---------------------+--------------------------------+ | c_int | c_bigint | c_float | c_double | c_decimal | +--------+-------------+---------+---------------------+--------------------------------+ | 214748 | 92233720368 | 3.40282 | 1.7976931348623157 | 123456789123456789.1234567890 | +--------+-------------+---------+---------------------+--------------------------------+ 1 row in set读取远端
test库中的number_t表,并和本地的number_t表做 JOIN 操作。obclient> SELECT a.c_decimal, b.c_double FROM number_t a, number_t@ob_dblink b where a.c_int = b.c_int; +--------------------------------+---------------------+ | c_decimal | c_double | +---------------------+--------------------------------+ | 123456789123456789.1234567890 | 1.7976931348623157 | +---------------------+--------------------------------+ 1 row in set读取远端
mysql库中的datetime_t表。obclient> SELECT * FROM mysql.datetime_t@ob_dblink; +-------------+------------+---------+----------------------+----------------------+ | c_date | c_time | c_year | c_datetime | c_timestamp | +-------------+------------+---------+-----------------------+---------------------+ | 2023-04-13 | 12:12:12 | 2078 | 2100-11-01 12:12:13 | 2100-12-01 21:14:15 | +-------------+------------+---------+----------------------+----------------------+ 1 row in set