SELECT
功能描述
SELECT 操作是只读的,不会修改数据库中的任何数据,但能以各种方式组合和转换数据,为报表生成、数据分析和应用程序查询提供基础。
注意事项
SELECT 语句涉及大量子句和连接操作时,请注意列别名、分组字段和排序字段的匹配关系;使用 FOR UPDATE 会对结果行加锁,可能影响并发性能。
语法格式
SELECT [DISTINCT] column1, column2, ... | [*] | expression
FROM TABLE_NAME | VIEW_NAME | SUBQUERY
[WHERE condition]
[ [ START WITH condition ] CONNECT BY [NOCYCLE] condition [ ORDER SIBLINGS BY expression ] ]
[GROUP BY {cube | rollup} column_list]
[HAVING condition]
[ { UNION | INTERSECT | EXCEPT | MINUS } [ ALL | DISTINCT ] select ]
[ORDER BY column_list | expression [ASC|DESC]]
[LIMIT offset, count]
[ {FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } [ OF table_name [, ...] ] [ NOWAIT | WAIT N]} [...] ];以下示例均基于表
CREATE TABLE employees (
employee_id NUMBER PRIMARY KEY,
name VARCHAR2(20) NOT NULL,
manager_id NUMBER,
department_id NUMBER,
job_title VARCHAR2(20),
salary NUMBER,
hire_date DATE
);
INSERT INTO employees VALUES (1, 'CEO', NULL, 10, 'CEO', 150000, SYSDATE);
INSERT INTO employees VALUES (2, 'Manager1', 1, 10, 'Manager', 100000, SYSDATE);
INSERT INTO employees VALUES (3, 'Manager2', 1, 20, 'Manager', 95000, SYSDATE);
INSERT INTO employees VALUES (4, 'Developer1', 2, 10, 'Developer', 85000, SYSDATE);
INSERT INTO employees VALUES (5, 'Developer2', 2, 10, 'Developer', 80000, SYSDATE);
COMMIT;参数说明
| 参数 | 说明 |
|---|---|
| DISTINCT | 可选,去重。 |
| column1, column2, ... / * / expression | 指定要查询的列或表达式。 |
| FROM | 指定数据源。 |
| WHERE | 行过滤条件。 |
| GROUP BY | 分组。 |
| HAVING | 组过滤条件。 |
| ORDER BY | 结果排序。 |
| LIMIT | 限制返回行数。 |
| FOR UPDATE / SHARE ... | 锁定子句。 |
[DISTINCT]: (可选) 用于从查询结果中移除重复行。
- DISTINCT与ORDER BY一同使用时,ORDER BY中排序的列必须包括在SELECT语句所检索的结果集的列中。
SQL> SELECT DISTINCT department_id, job_title FROM employees ORDER BY department_id, job_title; DEPARTMENT_ID JOB_TITLE ---------------------------------------- -------------------- 10 CEO 10 Developer 10 Manager 20 Manager 4 rows fetched.column1, column2, ... | [*] | expression: 指定要查询的结果。
- [] 可以使用星号 表示查询所有列。
- expression 可以是常量、表达式、函数调用等。
SELECT * FROM employees; SELECT department_id, job_title FROM employees; SQL> SELECT department_id + 100, UPPER(job_title) FROM employees WHERE department_id = 10; DEPARTMENT_ID + 100 UPPER(JOB_TITLE) ---------------------------------------- -------------------- 110 CEO 110 MANAGER 110 DEVELOPER 110 DEVELOPER 4 rows fetched.FROM TABLE_NAME | VIEW_NAME | SUBQUERY: 指定要查询的数据源表, 可以是表、视图或子查询。
SQL> CREATE OR REPLACE VIEW employee_view AS SELECT * FROM employees WHERE department_id = 10; Succeed. SQL> SELECT department_id, name FROM employee_view WHERE job_title = 'Manager'; DEPARTMENT_ID NAME ---------------------------------------- -------------------- 10 Manager1 1 rows fetched. SQL> SELECT department_id, name FROM (SELECT * FROM employees WHERE department_id = 10) WHERE job_title = 'Manager'; DEPARTMENT_ID NAME ---------------------------------------- -------------------- 10 Manager1 1 rows fetched.[WHERE condition]: (可选) WHERE子句构成一个行选择表达式,用来缩小SELECT查询的范围。condition是返回值为布尔型的任意表达式,任何不满足该条件的行都不会被检索。
- 常用的条件包括: =、<>[!=]、>、<、>=、<=、AND、OR、BETWEEN AND、IN、LIKE [ESCAPE]、IS [NOT] NULL、[NOT] IN、[NOT] EXISTS等
sqlSELECT * FROM employees WHERE department_id = [!=] | [>] | [<] | [>=] | [<=] 10; SELECT * FROM employees WHERE job_title [NOT] LIKE '%Sales\%' ESCAPE '\'; SELECT * FROM employees WHERE salary [NOT] BETWEEN 5000 AND 10000; SELECT * FROM employees WHERE manager_id IS [NOT] NULL; SELECT * FROM employees WHERE department_id [NOT] IN (10, 20, 30);[START WITH condition]: (可选) 用于指定递归查询的起始条件。
- START WITH子句通常与CONNECT BY子句同时出现,数据进行层次递归遍历查询,START WITH代表递归的初始条件。若省略该子句,单独使用CONNECT BY子句,则表示以表中的所有行作为初始集合。
[CONNECT BY [NOCYCLE] condition]: (可选) 用于指定递归查询的连接条件。
- CONNECT BY代表递归连接条件,和START WITH子句一起使用,实现数据遍历递归的功能。除此之外,PRIOR关键字还可以用在目标列中,允许用户通过目标列获取上一层的值。
[ORDER SIBLINGS BY expression]: (可选) 用于对递归查询结果的子行进行排序。
- ORDER SIBLINGS BY通常和START WITH、CONNECT BY子句同时使用,用法和ORDER BY子句一样,用于在递归过程中的层级排序。
SQL> SELECT LPAD(' ', 2 * LEVEL) || name AS employee_name, department_id 2 FROM employees 3 START WITH manager_id IS NULL 4 CONNECT BY PRIOR employee_id = manager_id 5 ORDER SIBLINGS BY name; EMPLOYEE_NAME DEPARTMENT_ID ---------------------------------------------------------------- ---------------------------------------- CEO 10 Manager1 10 Developer1 10 Developer2 10 Manager2 20 5 rows fetched.[GROUP BY {cube | rollup} column_list]: (可选) 用于对查询结果进行分组。
- GROUPING SETS ( grouping_element [, ...] ): GROUPING SETS子句是GROUP BY子句的进一步扩展,它可以使用户指定多个GROUP BY选项。 这样做可以通过裁剪用户不需要的数据组来提高效率。
SQL> SELECT department_id, job_title, SUM(salary) AS total_salary 2 FROM employees 3 GROUP BY department_id, job_title 4 ORDER BY department_id, job_title; DEPARTMENT_ID JOB_TITLE TOTAL_SALARY ---------------------------------------- -------------------- ---------------------------------------- 10 CEO 150000 10 Developer 165000 10 Manager 100000 20 Manager 95000 4 rows fetched.- CUBE (expression, ...): CUBE是自动对GROUP BY子句中列出的字段进行分组汇总,结果集将包含维度列中各值的所有可能组合,以及与这些维度值组合相匹配的基础行中的聚合值。它会为每个分组返回一行汇总信息,用户可以使用CUBE来产生交叉表值。比如,在CUBE子句中给出三个表达式(n = 3),运算结果为2n = 23 = 8组。以n个表达式的值分组的行称为常规行,其余的行称为超级聚集行。
-- GROUP BY CUBE 逻辑等价 -- CUBE (c1,c2,c3) <--> GROUPING SETS ((c1, c2, c3),(c1, c2),(c2, c3),(c1, c3),(c1),(c2),(c3),()) SQL> SELECT department_id, job_title, SUM(salary) AS total_salary 2 FROM employees 3 GROUP BY CUBE(department_id, job_title) 4 ORDER BY department_id, job_title; DEPARTMENT_ID JOB_TITLE TOTAL_SALARY ---------------------------------------- -------------------- ---------------------------------------- 10 CEO 150000 10 Developer 165000 10 Manager 100000 10 415000 20 Manager 95000 20 95000 CEO 150000 Developer 165000 Manager 195000 510000 10 rows fetched.- ROLLUP是生成多个分组集合的快捷功能。与CUBE子句的差异是,ROLLUP不生成基于特定列所有可能的分组集合,生成分组集合为其子集。ROLLUP假设输入列之间存在层次结构,从而生成有意义的所有分组集合。
-- GROUP BY ROLLUP 逻辑等价 -- ROLLUP(c1,c2,c3) <--> GROUPING SETS ((c1, c2, c3),(c1, c2),(c1),()) SQL> SELECT department_id, job_title, SUM(salary) AS total_salary 2 FROM employees 3 GROUP BY ROLLUP(department_id, job_title) 4 ORDER BY department_id, job_title; DEPARTMENT_ID JOB_TITLE TOTAL_SALARY ---------------------------------------- -------------------- ---------------------------------------- 10 CEO 150000 10 Developer 165000 10 Manager 100000 10 415000 20 Manager 95000 20 95000 510000 7 rows fetched.- 如果SELECT列表的表达式中引用了那些没有分组的字段,SQL会报错,除非使用了聚集函数或者该字段函数依赖于分组的字段,因为对于未分组的字段,可能返回多个数值。
[HAVING condition]: (可选) 用于对分组后的结果进行筛选。
- 与GROUP BY子句配合用来选择特殊的组。HAVING子句将组的一些属性与一个常数值比较,只有满足HAVING子句中的逻辑表达式的组才会被提取出来。
SQL> SELECT department_id, AVG(salary) AS avg_salary 2 FROM employees 3 GROUP BY department_id 4 HAVING AVG(salary) > 85000 -- 分组后筛选 5 ORDER BY department_id; DEPARTMENT_ID AVG_SALARY ---------------------------------------- ---------------------------------------- 10 103750 20 95000 2 rows fetched.[{ UNION | INTERSECT | EXCEPT | MINUS } [ ALL | DISTINCT ] SELECT]: (可选) 用于多个查询结果集的集合操作,要求子查询两端的列数和数据类型必须一致或兼容。
- UNION计算多个SELECT语句返回行集合的并集。
- 除非声明了ALL子句,否则默认的UNION结果不包含重复的行
- 同一个SELECT语句中的多个UNION操作符是从左向右计算的,除非用()进行优先级标识
sqlSELECT employee_id, name, department_id FROM employees WHERE department_id = 10 UNION [ALL] SELECT employee_id, name, department_id FROM employees WHERE department_id = 20 AND job_title = 'Manager';- INTERSECT计算多个SELECT语句返回行集合的交集
- 除非声明了ALL子句,否则默认的INTERSECT结果不包含重复的行
- 同一个SELECT语句中的多个INTERSECT操作符是从左向右计算的,除非用()进行优先级标识
- 当对多个SELECT语句的执行结果进行UNION和INTERSECT操作的时候,会优先处理INTERSECT
sqlSELECT employee_id, name, department_id FROM employees WHERE department_id = 10 INTERSECT [ALL] SELECT employee_id, name, department_id FROM employees WHERE department_id = 20 AND job_title = 'Manager';- EXCEPT计算多个SELECT语句返回行集合的差集
- 除非声明了ALL子句,否则默认的EXCEPT结果不包含重复的行
- EXCEPT操作符计算存在于左边SELECT语句的输出而不存在于右边SELECT语句输出的行
- 使用ALL时,一个在左边表中有m个重复而在右边表中有n个重复的行将在结果中出现max(m-n,0) 次
- 同一个SELECT语句中的多个EXCEPT操作符是从左向右计算的,除非用()进行优先级标识
- EXCEPT和UNION的绑定级别相同
sqlSELECT employee_id, name, department_id FROM employees WHERE department_id = 10 EXCEPT [ALL] SELECT employee_id, name, department_id FROM employees WHERE department_id = 20 AND job_title = 'Manager';- MINUS计算多个SELECT语句返回行集合的差集, 与EXCEPT操作符功能相同, 但是不能与ALL子句一起使用
- UNION计算多个SELECT语句返回行集合的并集。
[ORDER BY column_list | expression [ASC|DESC]]: (可选) 用于对查询结果进行排序。
- 当ORDER BY表达式中包含多列或者表达式时,排序优先级从左到右。
- 在与DISTINCT关键字一起使用的情况下,ORDER BY中排序的列必须包括在SELECT语句所检索的结果集的列中。
- ORDER BY可以支持表达式,其中引用的列必须在DISTINCT中
- 在与GROUP BY子句一起使用的情况下,ORDER BY中排序的列必须包括在SELECT语句所检索的结果集的列中。
[LIMIT offset, count]: (可选) 用于限制查询结果返回的行数,offset表示起始位置,count表示返回的行数。
- 当LIMIT子句中只指定一个参数时,默认从结果集的第一行开始返回。
SQL> SELECT employee_id, name, department_id, salary 2 FROM employees 3 ORDER BY employee_id 4 LIMIT 2, 2; -- 跳过前 2 条,返回接下来的 2 条 EMPLOYEE_ID NAME DEPARTMENT_ID SALARY ---------------------------------------- -------------------- ---------------------------------------- ---------------------------------------- 3 Manager2 20 95000 4 Developer1 10 85000 2 rows fetched.[FOR UPDATE]: (可选) 用于指定查询时对所查询数据的行进行加锁。
sqlSELECT employee_id, name, department_id, salary FROM employees ORDER BY employee_id FOR UPDATE; -- 对查询结果中的每一行加行级锁
JOIN 语法
JOIN 是 SQL 中用于将多个表连接起来的操作,通过连接条件将不同表中的数据组合在一起,形成有意义的结果集。
基本语法结构
SELECT column1, column2, ... | expression | function
FROM [Schema.]{table1 | view1 | subquery1} [alias1]
{JOIN TYPE} JOIN [Schema.]{table2 | view2 | subquery2} [alias2]
ON alias1.{column | expression | function} = alias2.{column | expression | function}
{JOIN TYPE} JOIN [Schema.]{table3 | view3 | subquery3} [alias3]
ON alias2.{column | expression | function} = alias3.{column | expression | function}
···
{JOIN TYPE} JOIN [Schema.]{tableN | viewN | subqueryN} [aliasN]
ON alias(N-1).{column | expression | function} = aliasN.{column | expression | function}
[WHERE conditions]
[GROUP BY columns]
[HAVING conditions]
[ORDER BY columns];- {JOIN TYPE}: 用于指定连接类型,包括[ INNER ] JOIN、LEFT [ OUTER ] JOIN、RIGHT [ OUTER ] JOIN、FULL [ OUTER ] JOIN等。
- INNER JOIN: 返回两个表中连接条件完全匹配的行,即两个表的交集部分。
- LEFT [ OUTER ] JOIN: 返回左表(FROM后第一个表)的所有行,即使右表没有匹配的行。右表不匹配的部分用NULL填充。
- RIGHT [ OUTER ] JOIN: 返回右表(JOIN后第二个表)的所有行,即使左表没有匹配的行。左表不匹配的部分用NULL填充。
- FULL [ OUTER ] JOIN: 返回左表和右表所有行,不匹配的部分用NULL填充。
- aliasN: (可选)用于为表、视图或子查询指定别名,以便在后续的查询中引用。
- alias(N-1).{column | expression | function} = aliasN.{column | expression | function}: 用于指定连接条件,即两个表中用于匹配的结果,可以是列、表达式、函数等。
[ INNER ] JOIN
- 返回两个表中连接条件完全匹配的行,即两个表的交集部分。
- 使用时可省略INNER,语义相同
create table t_join_1(a int, b int, c int);
create table t_join_2(a int, b int, c int);
insert into t_join_1 values(1,1,1),(2,2,2),(3,3,3),(4,4,4);
insert into t_join_2 values(1,1,1),(2,2,2),(3,3,3),(5,5,5);
-- 以表t_join_1为左表, 表t_join_2为右表, 以a列和b列进行内连接
SQL> select * from t_join_1 t1 inner join t_join_2 t2 on t1.a = t2.b;
A B C A B C
------------ ------------ ------------ ------------ ------------ ------------
1 1 1 1 1 1
2 2 2 2 2 2
3 3 3 3 3 3
3 rows fetched.LEFT [ OUTER ] JOIN
- 返回左表(FROM 后, LEFT JOIN 前的第一个表)的所有行,即使右表没有满足连接匹配条件的行。右表不匹配的部分数据用 NULL 值填充。
- 使用时可省略OUTER,语义相同
-- 以表t_join_1为左表, 表t_join_2为右表, 以a列和b列进行左外连接
SQL> select * from t_join_1 t1 left outer join t_join_2 t2 on t1.a = t2.b;
A B C A B C
------------ ------------ ------------ ------------ ------------ ------------
1 1 1 1 1 1
2 2 2 2 2 2
3 3 3 3 3 3
4 4 4
4 rows fetched.RIGHT [ OUTER ] JOIN
- 与 LEFT [ OUTER ] JOIN 语义相反,返回右表(JOIN 后第一个表)的所有行,即使左表没有满足连接匹配条件的行。左表不匹配的部分数据用 NULL 值填充。
- 使用时可省略OUTER,语义相同
- 这只是一个符号上的方便,因为所有的 RIGHT [ OUTER ] JOIN 总是可以把它转换成一个LEFT OUTER JOIN,只要把左边和右边的输入互换位置即可。
-- 以表t_join_1为左表, 表t_join_2为右表, 以a列和b列进行右外连接
SQL> select * from t_join_1 t1 right outer join t_join_2 t2 on t1.a = t2.b;
A B C A B C
------------ ------------ ------------ ------------ ------------ ------------
1 1 1 1 1 1
2 2 2 2 2 2
3 3 3 3 3 3
5 5 5
4 rows fetched.FULL [ OUTER ] JOIN
- 返回所有满足连接条件的结果行,除此之外,加上每个不匹配的左表行(右表用NULL值填充扩展),再加上每个不匹配的右表行(左表用NULL值填充扩展)。
- 使用时可省略OUTER,语义相同
-- 以表t_join_1为左表, 表t_join_2为右表, 以a列和b列进行全外连接
SQL> select * from t_join_1 t2 full outer join t_join_2 t1 on t2.b = t1.a;
A B C A B C
------------ ------------ ------------ ------------ ------------ ------------
1 1 1 1 1 1
2 2 2 2 2 2
3 3 3 3 3 3
4 4 4
5 5 5
5 rows fetched.CROSS JOIN
- 返回两个表的笛卡尔积(所有可能的行组合),不指定连接条件,即 SQL 语句中没有 ON 子句。
- CROSS JOIN等效于INNER JOIN ON(TRUE),即左右两张表的所有行组合。这种连接类型只是符号上的方便,因为它们与简单的FROM和WHERE的效果相同。
- 最后返回的结果集行数为左表行数乘以右表行数。
-- 以表t_join_1为左表, 表t_join_2为右表, 进行交叉连接
SQL> select * from t_join_1 t1 cross join t_join_2 t2;
A B C A B C
------------ ------------ ------------ ------------ ------------ ------------
1 1 1 1 1 1
1 1 1 2 2 2
1 1 1 3 3 3
1 1 1 5 5 5
2 2 2 1 1 1
2 2 2 2 2 2
2 2 2 3 3 3
2 2 2 5 5 5
3 3 3 1 1 1
3 3 3 2 2 2
3 3 3 3 3 3
3 3 3 5 5 5
4 4 4 1 1 1
4 4 4 2 2 2
4 4 4 3 3 3
4 4 4 5 5 5
16 rows fetched.WHERE (+) 语法
oGRAC 支持在WHERE子句中通过指定"(+)"操作符的方法将表的连接关系转换为外连接。该语法并不是SQL的标准语法,在做平台迁移的时候可能面临语法兼容性问题。同时,使用"(+)"有很多限制:
- "(+)"只能出现在WHERE子句中。如果FROM子句中已经指定了表连接关系,那么不能再在WHERE子句中使用"(+)"。
-- 错误示例:在from子句中已经有指定表连接关系,不能再在where子句中使用 "(+)" 会报错
SQL> SELECT * FROM t_join_1 t1 JOIN t_join_2 t2 ON t1.a = t2.a WHERE t1.b = t2.b (+);
OG-00601, Sql syntax error: the 'join' keyword is not allowed when exist '(+)'- "(+)"只能作用在表或视图的列上,不能作用在表达式上。
-- 错误示例:在表达式中使用 "(+)" 会报错
SQL> SELECT * FROM t_join_1 t1, t_join_2 t2 WHERE (t1.a + 1)(+) = t2.a;
OG-00601, [1:57]Sql syntax error: invalid word '(+)' found
SQL> SELECT * FROM t_join_1 t1, t_join_2 t2 WHERE (t1.a + 1) = t2.a(+);
A B C A B C
------------ ------------ ------------ ------------ ------------ ------------
1 1 1 2 2 2
2 2 2 3 3 3
3 3 3
4 4 4 5 5 5
4 rows fetched.- 如果表A和表B有多个连接条件,那么必须在所有的连接条件中指定"(+)",否则"(+)"将不会生效,表连接会转化成内连接,并且不给出任何提示信息。
-- 错误示例:仅在部分条件使用 "(+)" 转换成内连接 无任何报错信息
SQL> SELECT * FROM t_join_1 t1, t_join_2 t2 WHERE t1.a = t2.a (+) AND t1.b = t2.b;
A B C A B C
------------ ------------ ------------ ------------ ------------ ------------
1 1 1 1 1 1
2 2 2 2 2 2
3 3 3 3 3 3
3 rows fetched.- "(+)"作用的表达式不能通过"OR"直接连接。
-- 错误示例:直接通过 "OR" 连接 "(+)" 表达式会报错
SQL> SELECT * FROM t_join_1 t1, t_join_2 t2 WHERE t1.a = t2.a(+) OR t1.b = t2.b;
OG-00601, [1:53]Sql syntax error: invalid usage outer join symbol- 如果"(+)"作用的列是和一个常量的比较关系, 那么这个表达式会成为join条件的一部分。
SQL> SELECT *
2 FROM t_join_1, t_join_2
3 WHERE t_join_1.a = t_join_2.a (+) -- 正常连接条件
4 AND t_join_2.b (+) = 1; -- (t_join_2.b = 1) 成为连接条件的一部分
A B C A B C
------------ ------------ ------------ ------------ ------------ ------------
1 1 1 1 1 1
2 2 2
3 3 3
4 4 4
4 rows fetched.- "(+)"只能转化为左外连接或右外连接,不能转化为全连接,即不能在一个表达式的两个表上同时指定"(+)"。
-- 错误示例:在一个表达式的两个表上同时指定 "(+)" 会报错
SQL> SELECT * FROM t_join_1 t1, t_join_2 t2 WHERE t1.a = t2.a(+) AND t1.b(+) = t2.b;
OG-00601, Sql syntax error: failed to generate join tree when using '(+)'分区表数据查询
对分区表执行 SELECT 查询时,SQL 语法与普通表基本一致,但可通过特定方式利用分区特性提升性能。
基本语法
分区表数据查询的基本语法与普通表查询基本一致,只是在 FROM 子句中可以指定查询的分区或子分区。
SELECT columns | expression | function
FROM [schema.]table_name [PARTITION (partition_name) | SUBPARTITION (subpartition_name)] [alias1]
[{JOIN TYPE} JOIN [Schema.]{table_name [PARTITION (partition_name) | SUBPARTITION (subpartition_name)] | view | subquery} [alias2]]
[WHERE conditions]
[GROUP BY columns]
[HAVING conditions]
[ORDER BY columns];示例
-- 查询分区表的指定分区数据
SELECT * FROM table_name PARTITION (partition_name) where conditions;
-- 查询分区表特定子分区数据
SELECT * FROM table_name SUBPARTITION (subpartition_name) WHERE conditions;
-- 指定分区的 JOIN 语句 查询表 sales 子分区 p_2024_q3_north 与表 products 关联的记录
SELECT s.sale_id, p.product_name, s.amount FROM sales SUBPARTITION (p_2024_q3_north) s JOIN products p ON s.product_id = p.product_id;EXPLAIN 语句
EXPLAIN语句用于显示SQL语句的执行计划。通过分析SQL语句的EXPLAIN信息,可以了解SQL语句的执行计划、索引使用情况、索引扫描方式、表JOIN连接方式等信息,从而优化SQL语句执行的性能。
基本语法
EXPLAIN [PLAN FOR] SQL_QUERY;- EXPLAIN [PLAN FOR]: PLAN FOR 字段可选,与 EXPLAIN 语句功能相同,用于显示 SQL 语句的执行计划。
- SQL_QUERY: 要分析的 SQL 语句,DML 语句仅满足 SELECT、DELETE、UPDATE,其必须是一个合法的 SQL 语句,满足特定语句的语法规则,否则报错。
示例
SQL> explain select * from t_join_1 t1 left outer join t_join_2 t2 on t1.a = t2.b;
EXPLAIN PLAN OUTPUT
----------------------------------------------------------------
--------------------------------------------------------------------------------------
| Id | Operation | Owner | Name | Rows | Cost | Bytes | Remark |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | 0 | 20000 | | |
| 1 | NESTED LOOPS OUTER | | | 0 | 20000 | | |
| 2 | TABLE ACCESS FULL | SYS | T_JOIN_1 T1 | 0 | 10000 | | |
| 3 | TABLE ACCESS FULL | SYS | T_JOIN_2 T2 | 0 | 10000 | | |
--------------------------------------------------------------------------------------
Predicate Information (identified by id):
-----------------------------------------
3 - filter: T1.A = T2.B
11 rows fetched.
SQL> EXPLAIN PLAN FOR SELECT LPAD(' ', 2 * LEVEL) || name AS employee_name, department_id
2 FROM employees
3 START WITH manager_id IS NULL
4 CONNECT BY PRIOR employee_id = manager_id
5 ORDER SIBLINGS BY name;
EXPLAIN PLAN OUTPUT
----------------------------------------------------------------
-------------------------------------------------------------------------------------------
| Id | Operation | Owner | Name | Rows | Cost | Bytes | Remark |
-------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | 0 | 0 | | |
| 1 | QUERY SORT SIBLINGS ORDER BY | | | 0 | 0 | | |
| 2 | START WITH | | | 0 | 0 | | |
| 3 | TABLE ACCESS FULL | SYS | EMPLOYEES | 0 | 10000 | | |
| 4 | CONNECT BY | | | 0 | 0 | | |
| 5 | TABLE ACCESS FULL | SYS | EMPLOYEES | 0 | 10000 | | |
-------------------------------------------------------------------------------------------
Predicate Information (identified by id):
-----------------------------------------
2 - filter: MANAGER_ID IS NULL
3 - filter: MANAGER_ID IS NULL
4 - filter: PRIOR EMPLOYEE_ID = MANAGER_ID
15 rows fetched.示例
-- 查询所有员工
SELECT * FROM employees;
-- 查询指定部门并按工资排序
SELECT name, salary FROM employees WHERE department_id = 10 ORDER BY salary DESC;
-- 使用聚合函数统计各部门平均工资
SELECT department_id, AVG(salary) AS avg_salary FROM employees GROUP BY department_id;