---
title: "SIMPLE SELECT - OceanBase 数据库 V4.6.0 | OceanBase 文档中心"
description: "SIMPLE SELECT SELECT 的语法相对比较复杂，本节将介绍 SIMPLE SELECT 语法结构。 描述 该语句用于从表或视图中查询数据。 语法 simple_select: SELECT [ hint_options ] [ DISTINCT | UNIQUE | ALL] select_expr_l…"
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*P8CuR4UJ_FkAAAAAAAAAAAAADiGDAQ/original) OceanBase 数据库分布式版 - V 4.6.0

# SIMPLE SELECT

更新时间：2026-04-30 18:31:43

[编辑](https://github.com/oceanbase/oceanbase-doc/edit/V4.6.0/zh-CN/700.reference/500.sql-reference/100.sql-syntax/300.common-tenant-of-oracle-mode/900.sql-statement-of-oracle-mode/200.dml-of-oracle-mode/500.select-of-oracle-mode/100.simple-select-of-oracle-mode.md)  

SELECT 的语法相对比较复杂，本节将介绍 SIMPLE SELECT 语法结构。

## 描述

该语句用于从表或视图中查询数据。

## 语法

```sql
simple_select:
    SELECT [ hint_options ] [ DISTINCT | UNIQUE | ALL] select_expr_list
    FROM from_list
    [WHERE condition]
    [hierarchical_query_clause]
    [GROUP BY group_expression_list
        [{ROLLUP | CUBE | GROUPING SETS} group_expression_list]
        [HAVING condition]
     ]
    [ORDER BY order_expression_list]
    [FOR UPDATE [OF column] [ {NOWAIT | WAIT integer | SKIP LOCKED } ] ]
    [row_limiting_clause ]

select_expr_list:
    table_name.*
    | table_alias_name.*
    | expr [[AS] column_alias_name]
    | sequence_name.{ CURRVAL|NEXTVAL }@dblink_name

from_list:
    table_reference [, table_reference...]
    url_external_table_references

table_reference:
    simple_table
    | joined_table
    | pivot_clause
    | unpivot_clause
    | table_name@dblink_name

url_external_table_references:
     location_url | table_function

location_url:
  'file_path'
  (
  {FORMAT = (
      TYPE = 'CSV',
      LINE_DELIMITER = '<string>' | <expr>,
      FIELD_DELIMITER = '<string>' | <expr>,
      ESCAPE = '<character>' | <expr>,
      FIELD_OPTIONALLY_ENCLOSED_BY = '<character>' | <expr>,
      ENCODING = 'charset',
      NULL_IF = ('<string>' | <expr>, '<string>' | <expr> ...),
      SKIP_HEADER = <int>,
      SKIP_BLANK_LINES = { TRUE | FALSE },
      PARSE_HEADER = { TRUE | FALSE },
      TRIM_SPACE = { TRUE | FALSE },
      EMPTY_FIELD_AS_NULL = { TRUE | FALSE }
    )
   | FORMAT = ( TYPE = 'PARQUET' | 'ORC' )
  }
  [PATTERN = '<regex_pattern>']
  )

table_function:
  {
  FILES (
    LOCATION = {'file_path' | @location_name['/path']},
    {
      FORMAT = (
        TYPE = 'CSV',
        LINE_DELIMITER = '<string>' | <expr>,
        FIELD_DELIMITER = '<string>' | <expr>,
        ESCAPE = '<character>' | <expr>,
        FIELD_OPTIONALLY_ENCLOSED_BY = '<character>' | <expr>,
        ENCODING = 'charset',
        NULL_IF = ('<string>' | <expr>, '<string>' | <expr> ...),
        SKIP_HEADER = <int>,
        SKIP_BLANK_LINES = { TRUE | FALSE },
        PARSE_HEADER = { TRUE | FALSE },
        TRIM_SPACE = { TRUE | FALSE },
        EMPTY_FIELD_AS_NULL = { TRUE | FALSE }
      )
      | FORMAT = ( TYPE = 'PARQUET' | 'ORC' )
    },
    [PATTERN = '<regex_pattern>']
  )
  | SOURCE (
      TYPE = 'ODPS',
      ACCESSID = '<string>',
      ACCESSKEY = '<string>',
      ENDPOINT = '<string>',
      TUNNEL_ENDPOINT = '<string>',
      PROJECT_NAME = '<string>',
      SCHEMA_NAME = '<string>',
      TABLE_NAME = '<string>',
      QUOTA_NAME = '<string>',
      COMPRESSION_CODE = '<string>'
    )
  }

simple_table:
    (table_factor [partition_option])[table_alias_name]
    | (select_stmt)  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]

row_limiting_clause:
    [ OFFSET offset { ROW | ROWS } ]
    [ FETCH { FIRST | NEXT } [ { rowcount | percent PERCENT } ]
        { ROW | ROWS } { ONLY | WITH TIES } ]

pivot_clause：
    PIVOT
    (aggregate_function ( expr ) [[AS] alias ]
      [, aggregate_function ( expr ) [[AS] alias ]... ]
     pivot_for_clause
     pivot_in_clause
    )

pivot_for_clause：
    FOR { column| ( column [, column... ]) }

pivot_in_clause
    IN
    ( { { expr| ( expr [, expr...] ) } [ [ AS] alias]... }
       [, { { expr| ( expr [, expr...] ) } [ [ AS] alias] ...} ]
     )

unpivot_clause ：
    UNPIVOT [ {INCLUDE | EXCLUDE} NULLS ]
    ( { column | ( column [, column... ]) }
     pivot_for_clause
     unpivot_in_clause
     )

unpivot_in_clause：
    IN
    ( { column | ( column [, column... ]) }[ AS { literal | ( literal [, literal... ]) } ]
        [, { column | ( column [, column... ] ) }[ AS {literal | ( literal [, literal... ]) } ]]
    )

hierarchical_query_clause:
    [START WITH start_expression] CONNECT BY [NOCYCLE]
        {PRIOR child_expr = parent_expr
        | parent_expr = PRIOR child_expr} [ORDER SIBLINGS BY ...]

```

## 参数说明

| 字段 | 描述 |
| --- | --- |
| hint_options | 指定 Hint 选项，为可选项。 |
| DISTINCT \| UNIQUE \| ALL | 在查询的数据中，可能会包含重复行。   - 指定 `DISTINCT` 或 `UNIQUE`，表示在查询结果中相同的行只返回一行。`DISTINCT` 和 `UNIQUE` 是同义词。 - 指定 `ALL`，表示在查询结果中返回所有的行。默认为 `ALL`。 |
| select_expr_list | 指定从数据库列出要查询的表达式或列名，用","隔开。"*"表示所有列。   - `table_name.*`：指定从指定的表、视图中选择所有的列。 - `table_alias_name.`：指定表、视图的别名。 - `expr [[AS] column_alias_name]`：指定查询列或表达式的别名，`AS` 是可选的。 |
| FROM table_references | 指定选择数据的对象。 |
| url_external_table_references | 可选项，通过 URL 直接读取外表数据，当前 URL 外表支持两种语法形式，详细介绍可参见下文：   - [table_function](#table_function) 形式。 - [location_url](#location_url) 形式。 |
| PARTITION(partition_list) | 指定查询表的分区信息。例如：`partition(p0,p1...)`。 |
| table_factor | 指定表名（基表、可更新视图）、特殊子查询等，并支持直接查询函数。 |
| table_alias_name | 指定选择数据对象的别名。 |
| joined_table | 指定多表查询的联接方式。   - `[INNER] JOIN` 为内联接，`INNER` 为可选项。仅返回满足联接条件的数据。 - `[OUTER] JOIN` 为外联接，`OUTER` 为可选项。 - `LEFT [OUTER]` 表示左外联接。返回左表中的所有公共列值。 - `RIGHT [OUTER]` 表示右外联接。返回右表中的所有公共列值。 - `FULL [OUTER]` 表示全外联接。即除了内联接之外，两个表中未在内联接结果中返回的行将被保留并用空值扩展。 |
| ON expression | 指定多表联接的联接条件。 |
| WHERE where_conditions | 指定筛选条件，查询结果中仅包含满足条件的数据，为可选项。`where_conditions` 为表达式。 |
| hierarchical_query_clause | 可选项，指定层次查询选项，详细介绍可参见下文 [hierarchical_query_clause](#hierarchical_query_clause)。 |
| GROUP BY group_by_list | 指定分组的字段，通常与聚合函数配合使用。 **说明** 如果 `SELECT` 子句后面的列中没有使用聚合函数的列，则在分组查询中，`SELECT` 子句后面的列必须出现在 `GROUP BY` 子句中。 |
| ROLLUP group_expression_list | 合并 Group By 的分组，产生统计值。 |
| CUBE group_expression_list | 根据表达式列表中所有项的每个排列生成的分组进行聚合，并合并 `GROUP BY` 的分组，产生统计值。   **说明**：   - `select_expr_list` 中指定的各项必须也出现在 `CUBE expression_list` 中。 - `GROUP BY` 子句可指定多个 `CUBE` 扩展以及多次出现的其他 `GROUP BY` 扩展（例如 `ROLLUP`、`CUBE`、`GROUPING SETS`）和各表达式中，参考语法为 `SELECT select_expr_list FROM ... GROUP BY [..., ] CUBE (group_expression_list[, group_expression_list...]) [, ...]`。 - 如果未指定 `ORDER BY` 子句，则无法保证结果集的顺序。 - 分组级别数或总计数为 2 的 `n` 次幂，其中 `n` 表示 `CUBE` 表达式列表中的项数，即分组个数是表达式项数的指数级增长，由此不建议使用表达式项数较大的场景。 |
| GROUPING SETS group_expression_list | 在一个查询中指定多个数据分组，分别产生统计值，并将指定的分组统计值聚合显示。`GROUPING SETS` 中可以指定单个字段或字段列表。 |
| HAVING search_confitions | 筛选分组后的各组数据。`HAVING` 子句与 `WHERE` 子句类似，但是 `HAVING` 子句可以使用累计函数（如 `SUM`、`AVG` 等）。 |
| ORDER BY order_list | 指定结果集按照一个列或者多个列用来 `ASC` 或 `DESC` 显示查询结果。不指定 `ASC` 或者 `DESC` 时，默认为 `ASC`。   - `ASC` 表示升序。 - `DESC` 表示降序。 |
| row_limiting_clause | 用于限制查询返回的行，实现分页查询功能。可以指定偏移量，以及要返回的行数或行百分比。可以结合 `ORDER BY` 子句以确保排序顺序，从而获得一致的结果。 |
| OFFSET | 指定分页查询开始前要跳过的行数。`offset` 必须是数值或计算结果为数值的表达式。   - 如果指定负数，则 `offset` 将被视为 0。 - 如果指定为 `NULL` 或指定为大于或等于查询返回的行数的数量，则返回 0 行。 - 如果 `offset` 包含一个分数，则该分数部分将被截断。 - 如果未指定此子句，则偏移量为 0，从第一行开始分页。 |
| ROW \| ROWS | 表示单行或者多行，根据行数选择关键字，可以保证语义清晰。 |
| FETCH | 指定要返回的行数或行百分比。如果未指定此子句，则返回从 `offset`+1 开始的所有行。 |
| FIRST \| NEXT | 表示获取第一个返回的行数或行百分比或者下一个返回的行数或行百分比。 |
| rowcount \| percent PERCENT | 使用 `rowcount` 指定要返回的行数。`rowcount` 必须是一个数字或一个计算结果为数值的表达式。如果指定负数，则 `rowcount` 将被视为 0。如果 `rowcount` 大于从 `rowcount`+1 开始的可用行数，则返回所有可用行。如果 `rowcount` 包含一个分数，则该分数部分将被截断。如果 `rowcount` 为 `NULL`，则返回 0 行。使用 `percent PERCENT` 指定要返回的指定行总数的百分比。`percent` 必须是数值或计算为数值的表达式。如果指定为负数，则 `percent` 将被视为 0。如果 `percent` 为 `NULL`，则返回 0行。如果未指定 `rowcount` 或者 ``percent``PERCENT``，则返回 1 行。 |
| ONLY \| WITH TIES | 指定 `ONLY` 返回指定的行数或行百分比。指定 `WITH TIES` 返回与上次获取的行具有相同排序键的其他行。如果使用 `WITH TIES`，则必须指定 `ORDER BY` 子句。如果未指定 `ORDER BY` 子句，则不会返回其他行。 |
| FOR UPDATE | 可选项，对查询结果所有行加上排他锁，以阻止其他事务的并发修改，或阻止在某些事务隔离级别时的并发读取。   - `OF column`：对于多表 Join 的场景，使用该子句可以指示仅锁定某些表（即 `column` 指定列所在的表）的查询结果行。 - `NOWAIT`：立即对查询结果行尝试加锁如果查询结果行中已经有被其他会话加锁的行，则执行失败。 - `WAIT integer`：等待 `Interger` 时间后再对查询结果行尝试加锁，如果查询结果行中已经有被其他会话加锁的行，则执行失败。 - `SKIP LOCKED`：如果查询结果中已经有被其他会话加锁的行，则会跳过这些加锁行，返回未被加锁的行。     #### 注意      `SKIP LOCKED` 暂不支持多表 `JOIN` 加锁的场景。 |
| pivot_clause | 将行旋转为列的子句。   #### 注意    - 暂不支持 pivot 作为 joined table 的别名。 - 暂不支持 pivot 操作的目标表是 natural join 的情况。 |
| aggregate_function | 指定聚合函数。 |
| expr | 指定计算结果为常量值的表达式。 `pivot_in_clause` 只支持常量表达式。 |
| unpivot_clause | 将列旋转为行的子句。   #### 注意    - 暂不支持 unpivot 作为 joined table 的别名。 - 暂不支持 unpivot 操作的目标表是 natural join 的情况。 |
| dblink_name | 指定要访问的数据库链接（即 dblink）的名称。 |
| sequence_name | 通过 dblink 访问远端数据库（包括 OceanBase 数据库和 Oracle 数据库）中的序列值，包括计算 `SEQUENCE` 对象的 `NEXTVAL`、`CURRVAL` 值。 |

### hierarchical_query_clause

在层级查询中，可以在 `SELECT` 语句的列中使用一个特殊的伪列（pseudo column）`LEVEL`，表示等级，即节点的层次。由查询的起点开始算起，起点为 1，依次类推。使用层次查询时，才可以使用该字段。更多有关层级查询中伪列的信息，请参见 [层次查询伪列](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005686306)。

- `START WITH start_expression`：可选项，指定层次查询中的根行（Root Row）。
 - `CONNECT BY`：指定如何来确定父子关系，这里通常使用等值表达式，但其他表达式同样支持。
 - `NOCYCLE`：当指定该关键字时，即使返回结果中有循环仍旧可以返回，并可以通过 `CONNECT_BY_ISCYCLE` 虚拟列来指定哪里出现循环；否则，会给客户端报错。
 - `PRIOR child_expr = parent_expr | parent_expr = PRIOR child_expr`：`PRIOR` 是一元运算符，表示参数中的列来自于父行（Parent Row），与一元的 + 和 - 具有相同的优先级。
 - `ORDER SIBLINGS BY`：指定同一个层级行之间的排列顺序。

#### 注意

如果层次查询中包含了 `FOR UPDATE` 子句，那么不支持以下的使用场景：

- 如果子查询使用了 `DISTINCT` 关键字或者聚合，这种情况下将不能和 `FOR UPDATE` 一起使用。
 - 任何包含公共表达式（Common Table Expressions，CTE）的情景都不支持，即带有 `WITH ... AS ...` 子句的 `SELECT` 查询不能与 `FOR UPDATE` 同时使用。

更多有关层次查询的使用信息，请参见 [层次查询](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005686328)。

### table_function

- LOCATION 子句用于指定外表文件存放的路径。通常外表的数据文件存放于单独一个目录中，文件夹中可以包含子目录，在创建表时，外表会自动收集该目录中的所有文件。取值如下：

     - `file_path`：表示具体的外表文件路径信息，详细介绍如下：

           - 本地 LOCATION 格式为 `LOCATION = '[file://] local_file_path'`，其中 `local_file_path` 可以为相对路径，也可以为绝对路径。如果填写的是相对路径，则当前目录必须为 OceanBase 数据库的安装目录；`secure_file_priv` 用于配置 OBServer 节点有权限访问的文件路径。`local_file_path` 只能是 `secure_file_priv` 路径的子路径。
           - 远程 LOCATION 格式为 `LOCATION = '{oss | s3}://$ACCESS_ID:$ACCESS_KEY@$HOST:s3_region/remote_file_path'`，其中 `$ACCESS_ID`、`$ACCESS_KEY` 和 `$HOST` 是访问 OSS 和 S3 时需要配置的访问信息，s3_region 为使用 S3 时选择的区域信息，这些敏感的访问信息会以加密的方式存放在数据库的系统表中。
     - `@location_name['/path']`：表示引用 Location 对象创建外表。`['/path']` 为可选项，表示子目录。关于创建 Location 对象详细介绍信息，参见 [CREATE LOCATION](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005687554)。

      #### 说明

      对于 OceanBase 数据库 V4.4.x 版本，从 V4.4.1 版本开始支持 `@location_name['/path']` 参数。
 - FORMAT 子句用于指定读取文件格式相关的属性，支持 CSV/PARQUET/ORC 三种文件格式。

     - **TYPE = 'CSV'** 时，包含以下字段：
           - `LINE_DELIMITER`：指定 CSV 文件的行分隔符，默认为 `LINE_DELIMITER='\n'`。
           - `FIELD_DELIMITER`：可选项，指定 CSV 文件的列分隔符，默认为 `FIELD_DELIMITER='\t'`。
           - `ESCAPE`：指定 CSV 文件的转义符号，只能为 1 个字节，默认为 `ESCAPE ='\'`。
           - `FIELD_OPTIONALLY_ENCLOSED_BY`：可选项，指定 CSV 文件中包裹字段值的符号，默认为空。使用此选项表示只对部分类型的字段（如 CHAR, VARCHAR, TEXT, JSON 等）加包裹符。
           - `ENCODING`：指定文件的字符集编码格式，如果不指定，默认值为 `UTF8MB4`。
           - `NULL_IF`：指定被当作 `NULL` 处理的字符串。默认值为空。
           - `SKIP_HEADER`：跳过文件头，并指定跳过的行数。
           - `SKIP_BLANK_LINES`：指定是否跳过空白行。默认值为 `FALSE`，表示不跳过空白的行。
           - `TRIM_SPACE`：指定是否删除文件中字段的头部和尾部空格。默认值为 `FALSE`，表示不删除文件中字段头尾的空格。
           - `EMPTY_FIELD_AS_NULL`：指定是否将空字符串当作 `NULL` 处理。默认值为 `FALSE`，表示不将空字符串当做 `NULL` 处理。
           - `PARSE_HEADER`:指定该配置后直接获取 CSV 文件第一行信息，将其作为每列的列名。  

            #### 注意

            `PARSE_HEADER`不能和 `SKIP_HEADER` 同时使用，语意上会有冲突。
     - **TYPE = 'PARQUET/ORC'** 时，无其他额外字段。
 - `PATTERN` 子句指定一个正则模式串，用于过滤 `LOCATION` 目录下的文件。对于每个 LOCATION 目录下的文件路径，如果能够匹配该模式串，外表会访问这个文件，否则外表会跳过这个文件。如果不指定该参数，则默认可以访问 `LOCATION` 目录下的所有文件。

对于 ODPS 格式，因为获取数据的方式不是通过文件，并且不存在有意义的 URL 路径，所以只支持 `source` 这一种 table_function 的形式。

- **TYPE = 'ODPS'** 包含以下字段：
     - `ACCESSID`：指定 ODPS 用户的 ID。
     - `ACCESSKEY`：指定 ODPS 用户的密码。
     - `ENDPOINT`：指定 ODPS 服务的连接地址。
     - `TUNNEL_ENDPOINT`：指定 Tunnel 数据传输服务的连接地址。
     - `PROJECT_NAME`：指定需要查询的表所在的 Project。
     - `SCHEMA_NAME`：可选项，指定需要查询表的 SCHEMA。
     - `TABLE_NAME`：指定需要查询的表名。
     - `QUOTA_NAME`：可选项，选择是否使用指定的 Quota。
     - `COMPRESSION_CODE`：可选项，指定数据源的压缩格式，支持 ZLIB、ZSTD、LZ4、ODPS_LZ4 四种压缩格式，不设置表示不开启压缩。

### location_url

- `FORMAT` 子句用于指定读取件格式相关的属性，支持 CSV/PARQUET/ORC 三种文件格式，其中 CSV 文件需要配置 `parse_header` 用于指定是否解析文件的标题行，使用 TYPE 指定导出文件格式。对于 ODPS 的数据，需要使用 `source` 子句。

  **查询示例如下：**

  ```sql
  SELECT * FROM
  FILES( location = '/data/',
      format (TYPE = 'csv', field_delimiter = ',', parse_header = true),
      pattern = 'datafiles$';

  ```

## 示例

- 从表 `tbl1` 中读取 `name` 数据。

  ```sql
  obclient> CREATE TABLE tbl1 (id INT,name VARCHAR(10),num INT);
  Query OK, 0 rows affected

  obclient> INSERT INTO tbl1 VALUES (1, 'a',100),(2, 'b',200),(3, 'a',50);
  Query OK, 3 rows affected
  Records: 3  Duplicates: 0  Warnings: 0

  obclient> SELECT * FROM tbl1;
  +------+------+------+
  | ID   | NAME | NUM  |
  +------+------+------+
  |    1 | a    |  100 |
  |    2 | b    |  200 |
  |    3 | a    |   50 |
  +------+------+------+
  3 rows in set

  obclient> SELECT name FROM tbl1;
  +------+
  | NAME |
  +------+
  | a    |
  | b    |
  | a    |
  +------+
  3 rows in set

  ```
 - 从表 `tbl1` 中读取 `name` 数据并进行去重处理。

  ```sql
  obclient> SELECT DISTINCT name FROM tbl1;
  +------+
  | NAME |
  +------+
  | a    |
  | b    |
  +------+
  2 rows in set

  ```
 - 从表 `tbl1` 中查询 `id`、`name` 和 `num`，然后把 `num` 列除以 2 输出，输出的列名为 `avg`。

  ```sql
  obclient> SELECT id, name, num/2 AS avg FROM tbl1;
  +------+------+------+
  | ID   | NAME | AVG  |
  +------+------+------+
  |    1 | a    |   50 |
  |    2 | b    |  100 |
  |    3 | a    |   25 |
  +------+------+------+
  3 rows in set

  ```
 - 从表 `tbl1` 中根据筛选条件 `name = 'a'`，输出对应的 `id` 、`name` 和 `num`。

  ```javascript
  obclient> SELECT id, name, num FROM tbl1 WHERE name = 'a';
  +------+------+------+
  | ID   | NAME | NUM  |
  +------+------+------+
  |    1 | a    |  100 |
  |    3 | a    |   50 |
  +------+------+------+
  2 rows in set

  ```
 - 从表 `tbl1` 中查询 `name`，按照 `name` 分组对 `num` 求和，查询 `num` 总和小于 `160` 的行，并输出。

  ```sql
  obclient> SELECT name,SUM(num)  sum
                  FROM tbl1
                  GROUP BY name
                  HAVING SUM(num) < 160;
  +------+------+
  | NAME | SUM  |
  +------+------+
  | a    |  150 |
  +------+------+
  1 row in set

  ```
 - 从表 `tbl1` 中查询 `id`、`name` 和 `num`，根据 `num` 按升序输出查询结果。

  ```javascript
  obclient> SELECT * FROM tbl1 ORDER BY num ASC;
  +------+------+------+
  | ID   | NAME | NUM  |
  +------+------+------+
  |    3 | a    |   50 |
  |    1 | a    |  100 |
  |    2 | b    |  200 |
  +------+------+------+
  3 rows in set

  ```
 - 从表 `tbl1` 中查询所有列，根据 `name` 按降序，`num` 按升序输出查询结果。

  ```sql
  obclient> SELECT * FROM tbl1 ORDER BY name DESC,num ASC;
  +------+------+------+
  | ID   | NAME | NUM  |
  +------+------+------+
  |    2 | b    |  200 |
  |    3 | a    |   50 |
  |    1 | a    |  100 |
  +------+------+------+
  3 rows in set

  ```
 - 从表 `tbl1` 中查询指定 `id` 的行，并使用 `FOR UPDATE` 子句把查询结果行进行锁定。

  ```sql
  /* 在会话 1 中查询表 tbl1 中 id=1 的行并锁定 */
  obclient> SELECT * FROM tbl1 WHERE id=1 FOR UPDATE;
  +------+------+------+
  | ID   | NAME | NUM  |
  +------+------+------+
  |    1 | a    |  100 |
  +------+------+------+
  1 row in set

  /* 在会话 2 中查询表 tbl1 中 id=1 或 id=2 的行并锁定 */
  obclient> SELECT * FROM tbl1 WHERE id=1 or id=2 FOR UPDATE;
  OBE-30006: resource busy; acquire with WAIT timeout expired

  obclient> SELECT * FROM tbl1 WHERE id=1 or id=2 FOR UPDATE SKIP LOCKED;
  +------+------+------+
  | ID   | NAME | NUM  |
  +------+------+------+
  |    2 | b    |  200 |
  +------+------+------+
  1 row in set

  ```
 - 创建表 `group_tbl1`，并插入数据。执行带有 `CUBE` 的 `GROUP BY` 查询语句。

  ```shell
  obclient> CREATE TABLE group_tbl1 (group_id INT,job VARCHAR2(10),name VARCHAR2(10),salary INT);
  Query OK, 0 rows affected
  obclient> INSERT INTO group_tbl1 VALUES(10,'Coding','Bruce',1000),
      (10,'Programmer','Clair',1000),
      (20,'Coding','Jason',2000),
      (20,'Programmer','Joey',2000),
      (30,'Coding','Rebecca',3000),
      (30,'Programmer','Rex',3000);
  Query OK, 6 rows affected
  Records: 6  Duplicates: 0  Warnings: 0
   obclient> SELECT * FROM group_tbl1;
   +----------+------------+---------+--------+
   | GROUP_ID | JOB        | NAME    | SALARY |
   +----------+------------+---------+--------+
   |       10 | Coding     | Bruce   |   1000 |
   |       10 | Programmer | Clair   |   1000 |
   |       20 | Coding     | Jason   |   2000 |
   |       20 | Programmer | Joey    |   2000 |
   |       30 | Coding     | Rebecca |   3000 |
   |       30 | Programmer | Rex     |   3000 |
   +----------+------------+---------+--------+
   6 rows in set
   obclient> SELECT group_id, salary, SUM(salary) FROM group_tbl1 GROUP BY CUBE (group_id, salary);
   +----------+--------+-------------+
   | GROUP_ID | SALARY | SUM(SALARY) |
   +----------+--------+-------------+
   |     NULL |   NULL |       12000 |
   |     NULL |   1000 |        2000 |
   |     NULL |   2000 |        4000 |
   |     NULL |   3000 |        6000 |
   |       10 |   NULL |        2000 |
   |       20 |   NULL |        4000 |
   |       30 |   NULL |        6000 |
   |       10 |   1000 |        2000 |
   |       20 |   2000 |        4000 |
   |       30 |   3000 |        6000 |
   +----------+--------+-------------+
   10 rows in set

  ```
 - 从表 `tbl1` 中按 `name` 和 `num` 分组查询并统计每个分组中的数量。

  ```sql
  obclient> SELECT name, num, COUNT(*) from tbl1 GROUP BY GROUPING SETS(name, num);
  +------+------+----------+
  | NAME | NUM  | COUNT(*) |
  +------+------+----------+
  | a    | NULL |        2 |
  | b    | NULL |        1 |
  | NULL |  100 |        1 |
  | NULL |  200 |        1 |
  | NULL |   50 |        1 |
  +------+------+----------+
  5 rows in set

  ```
 - 将表 `emp_phone` 中的行转为列，再将列转为行。

  ```sql
  obclient> CREATE TABLE emp(name VARCHAR2(50), num CHAR, phone VARCHAR2(50));
  Query OK, 0 rows affected

  obclient> INSERT INTO emp VALUES('ZhangSan', '1', '1234-5678'),('ZhangSan', '2', '3219-6066'),('ZhangSan', '3', '5365-9583');
  Query OK, 3 rows affected
  Records: 3  Duplicates: 0  Warnings: 0

  obclient> SELECT * FROM emp;
  +----------+------+-----------+
  | NAME     | NUM  | PHONE     |
  +----------+------+-----------+
  | ZhangSan | 1    | 1234-5678 |
  | ZhangSan | 2    | 3219-6066 |
  | ZhangSan | 3    | 5365-9583 |
  +----------+------+-----------+
  3 rows in set

  /* 将表 emp 中的行转为列 */
  obclient> SELECT * FROM emp PIVOT(MAX(phone) FOR num IN (1 AS home, 2 AS office, 3 AS mobile));
  +----------+-----------+-----------+-----------+
  | NAME     | HOME      | OFFICE    | MOBILE    |
  +----------+-----------+-----------+-----------+
  | ZhangSan | 1234-5678 | 3219-6066 | 5365-9583 |
  +----------+-----------+-----------+-----------+
  1 row in set

  /* 将表 emp 中的列转为行 */
  obclient> CREATE VIEW v_emp AS SELECT * FROM emp PIVOT(MAX(phone) FOR num IN (1 AS home, 2 AS office, 3 AS mobile));
  Query OK, 0 rows affected

  obclient>  SELECT * FROM v_emp UNPIVOT(phone FOR num IN (home AS 1, office AS 2, mobile AS 3));
  +----------+-----+-----------+
  | NAME     | NUM | PHONE     |
  +----------+-----+-----------+
  | ZhangSan |   1 | 1234-5678 |
  | ZhangSan |   2 | 3219-6066 |
  | ZhangSan |   3 | 5365-9583 |
  +----------+-----+-----------+
  3 rows in set

  ```
 - 查询远端数据库的表中数据。

  ```sql
  /*访问远端的 OceanBase 数据库查询数据*/
  obclient> SELECT ID FROM tbl2@ob_dblink;
  +------+
  | ID   |
  +------+
  |    1 |
  |    2 |
  |    3 |
  +------+
  3 rows in set

  obclient> SELECT * FROM tbl2@ob_dblink;
  +------+------+------+
  | ID   | NAME | NUM  |
  +------+------+------+
  |    1 | a    |  100 |
  |    2 | b    |  200 |
  |    3 | a    |   50 |
  +------+------+------+
  3 rows in set

  /*访问远端的 Oracle 数据库查询数据*/
  obclient> SELECT ID FROM tbl2@ora_dblink;
  +------+
  | ID   |
  +------+
  |    1 |
  |    2 |
  |    3 |
  +------+
  3 rows in set

  obclient> SELECT * FROM tbl2@ora_dblink;
  +------+------+------+
  | ID   | NAME | NUM  |
  +------+------+------+
  |    1 | a    |  100 |
  |    2 | b    |  200 |
  |    3 | a    |   50 |
  +------+------+------+
  3 rows in set

  /*同时查询本地数据库和远端数据库的数据*/
  obclient> SELECT t4.col1,t5.col2 FROM tbl1 t4, tbl2@ob_dblink t5 WHERE t1.col3=t2.col3;

  /*同时查询不同的远端数据库的数据*/
  obclient> SELECT * FROM tbl2@ob_dblink t_remote1,tbl2@ora_dblink t_remote2 WHERE t_remote1.col1 = t_remote2.col1;

  ```
 - 分页查询示例

     - 查询员工编号 `empno` 最低的 3 名员工。

      ```sql
      obclient> CREATE TABLE emp(
          empno         NUMBER(4,0),
          empname       VARCHAR(10),
          job           VARCHAR(9),
          mgr           NUMBER(4,0),
          hiredate      DATE,
          sal           NUMBER(7,2),
          comm          NUMBER(7,2),
          deptno        NUMBER(2,0),
          CONSTRAINT PK_emp PRIMARY KEY (empno)
      );
      Query OK, 0 rows affected

      obclient> INSERT INTO emp VALUES (1839,'KING','PRESIDENT',null,'17-DEC-81',5000,null,10)
         ,(1698,'BLAKE','MANAGER',1839,'01-MAY-81',2850,null,30)
         ,(1782,'CLARK', 'MANAGER', 1839, '09-JUN-81', 2450, null, 10)
         ,(1566,'JONES','MANAGER',1839, '02-APR-81',2975,null,40)
         ,(1788,'SCOTT','ANALYST',1566, '15-JUL-87',3000,null,20)
         ,(1902,'FORD','ANALYST',1566, '05-OCT-81',3000,null,40)
         ,(1369,'SMITH','CLERK',1902, '17-NOV-80',800,null,20)
         ,(1499,'ALLEN','SALESMAN',1698, '20-FEB-81',1600,300,30);

      Query OK, 8 rows affected
      Records: 8  Duplicates: 0  Warnings: 0

      obclient> SELECT empno, empname FROM emp ORDER BY empno FETCH FIRST 3 ROWS ONLY;
      +-------+---------+
      | EMPNO | EMPNAME |
      +-------+---------+
      |  1369 | SMITH   |
      |  1499 | ALLEN   |
      |  1566 | JONES   |
      +-------+---------+
      3 rows in set

      ```
     - 再继续查询员工编号 `empno` 最低的 3 名员工。

      ```sql
      obclient> SELECT empno, empname
      FROM emp
      ORDER BY empno
      FETCH NEXT 3 ROWS ONLY;

      ```
     - 查询最低工资员工中前 25% 的员工。

      ```sql
      obclient> SELECT empno, empname sal FROM emp ORDER BY sal
       FETCH FIRST 25 PERCENT ROWS ONLY;
      +-------+-------+
      | EMPNO | SAL   |
      +-------+-------+
      |  1499 | ALLEN |
      |  1698 | BLAKE |
      +-------+-------+
      2 rows in set

      ```
     - 查询最低工资员工中前 25% 的员工，以及与上一个示例中获取的最后一位员工工资相同的所有其他员工。

      ```sql
      obclient> SELECT empno, empname sal FROM emp ORDER BY sal
       FETCH FIRST 25 PERCENT ROWS WITH TIES;
      +-------+-------+
      | EMPNO | SAL   |
      +-------+-------+
      |  1499 | ALLEN |
      |  1698 | BLAKE |
      +-------+-------+
      2 rows in set

      ```
 - 查询表 `t1` 的数据并指定表别名。

  ```shell
  obclient> CREATE TABLE t1 (c1 INT, c2 INT );
  Query OK, 0 rows affected

  obclient> INSERT INTO t1 VALUES ('1','2');
  Query OK, 1 row affected

  obclient> SELECT * FROM (t1) a;
  +------+------+
  | C1   | C2   |
  +------+------+
  |    1 |    2 |
  +------+------+
  1 row in set

  ```
 - 使用 `RANDOM()` 生成随机数，`FROM` 子句后直接查询 `GENERATOR()` 函数。

  ```shell
  obclient> SELECT RANDOM(4) FROM GENERATOR(3);
  +---------------------+
  | RANDOM(4)           |
  +---------------------+
  | 5267436225003336391 |
  | -851690886662571060 |
  | 1738617244330437274 |
  +---------------------+
  3 rows in set

  ```
 - 访问远端数据库中的序列值。

  1.登录本地 OceanBase 数据库，创建远端 OceanBase 数据库 Oracle 租户的 dblink。

  ```shell
  obclient> CREATE DATABASE LINK seq_link CONNECT TO test@oracle IDENTIFIED BY test HOST '127.xxx.xxx.xxx:2828';
  Query OK, 0 rows affected

  ```

  2.在远端的 OceanBase 数据库中，创建序列 `my_seq`。

  ```shell
  obclient> CREATE SEQUENCE my_seq START WITH 1 MINVALUE 1 MAXVALUE 10 INCREMENT BY 2 NOCYCLE NOORDER CACHE 30;
  Query OK, 0 rows affected

  ```

  3.在本地访问远端 OceanBase 数据库的序列值。

  ```shell
  obclient> SELECT my_seq.NEXTVAL@seq_link FROM DUAL;
  +---------+
  | NEXTVAL |
  +---------+
  |       1 |
  +---------+
  1 row in set

  obclient> SELECT my_seq.CURRVAL@seq_link FROM DUAL;
  +---------+
  | CURRVAL |
  +---------+
  |       1 |
  +---------+
  1 row in set

  obclient> SELECT my_seq.NEXTVAL@seq_link FROM DUAL;
  +---------+
  | NEXTVAL |
  +---------+
  |       3 |
  +---------+
  1 row in set

  ```

 上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
