子查询可以分为相关子查询和非相关子查询。相关子查询指该子查询的执行依赖了外部查询的变量,这种子查询通常会执行多次。非相关子查询指该子查询的执行不依赖外部查询的变量,这种子查询一般只需要计算一次。对于非相关子查询与部分相关子查询,可以通过改写进行子查询消除,实现嵌套子查询的展开。

如果子查询中的列与外层查询中的列具有相同列名,必须在外层查询中在重复列名前加上表名或使用别名。

当上层查询引用到子查询中相关列时,将执行子查询,上层查询可以是SELECTUPDATEDELETE语句,各语句中使用子查询方式:

  • 定义要插入到 INSERTCREATE TABLE 语句的目标表中的行集。
  • CREATE VIEWCREATE MATERIALIZED VIEW 语句中定义要包含在视图或物化视图中的行集。
  • UPDATE 中定义要分配给现有行的一个或多个值。
  • WHERE 子句、HAVING 子句或 START WITH 中提供条件值。
  • 定义包含查询操作的表。

以下情况数据库将进行嵌套子查询的展开:

  • 不相关的 IN 子查询。
  • INEXISTS 中的相关子查询不包含聚合函数或 GROUP BY 子句。

可以通过 Hint UNNEST 控制是否展开嵌套子查询。

以下语句创建了表 table_a和表 table_b,并向表中插入数据:

  1. CREATE TABLE table_a(PK INT, name VARCHAR(25));
  2. INSERT INTO table_a VALUES(1,'福克斯');
  3. INSERT INTO table_a VALUES(2,'警察');
  4. INSERT INTO table_a VALUES(4,'林肯');
  5. INSERT INTO table_a VALUES(5,'亚利桑那州');
  6. INSERT INTO table_a VALUES(6,'华盛顿');
  7. INSERT INTO table_a VALUES(7,'戴尔');
  8. INSERT INTO table_a VALUES(10,'朗讯');
  9. CREATE TABLE table_b(PK INT, name VARCHAR(25));
  10. INSERT INTO table_b VALUES(1,'福克斯');
  11. INSERT INTO table_b VALUES(3,'的士');
  12. INSERT INTO table_b VALUES(6,'华盛顿');
  13. INSERT INTO table_b VALUES(7,'戴尔');
  14. INSERT INTO table_b VALUES(8,'微软');
  15. INSERT INTO table_b VALUES(9,'苹果');
  16. INSERT INTO table_b VALUES(11,'苏格兰威士忌');

查询结果如下:

  1. +------+-----------+
  2. | PK | NAME |
  3. +------+-----------+
  4. | 1 | 福克斯 |
  5. | 2 | 警察 |
  6. | 3 | 的士 |
  7. | 6 | 华盛顿 |
  8. | 7 | 戴尔 |
  9. +------+-----------+

有依赖关系的子查询,子查询中用到了外层查询变量 T1.PK,执行以下语句:

查询结果如下:

  1. +------+-----------+
  2. +------+-----------+
  3. | 1 | 福克斯 |
  4. | 2 | 警察 |
  5. | 3 | 的士 |
  6. | 7 | 戴尔 |
  7. +------+-----------+

查询结果如下:

  1. +------------------------------------+
  2. | Query Plan |
  3. +------------------------------------+
  4. =============================================
  5. |ID|OPERATOR |NAME|EST. ROWS|COST|
  6. ---------------------------------------------
  7. |0 |HASH RIGHT SEMI JOIN| |8 |107 |
  8. |1 | TABLE SCAN |T2 |8 |38 |
  9. |2 | TABLE SCAN |T1 |8 |38 |
  10. =============================================
  11. Outputs & filters:
  12. -------------------------------------
  13. 0 - output([T1.PK], [T1.NAME]), filter(nil),
  14. equal_conds([T1.PK = T2.NAME], [T2.NAME = T1.NAME]), other_conds(nil)
  15. 1 - output([T2.NAME]), filter(nil),
  16. access([T2.NAME]), partitions(p0)
  17. 2 - output([T1.NAME], [T1.PK]), filter(nil),
  18. +------------------------------------+