相关子查询
相关子查询是引用不在其 FROM 子句中的列或表的子查询。该列可以在 Projection 子句
或 WHERE 子句中。
通常,相关子查询会降低性能。建议使用表名或表别名限制子查询中的列名。从而除去与
列所驻留的表相关的任何疑问。
下列查询是相关子查询的一个示例,它返回 orders 表中 10 个最近的装运日期的列表。它
在子查询之后加上 ORDER BY 子句以对结果进行排序,原因是(除在 FROM 子句以外)
您不能在子查询中包括 ORDER BY 。
图: 查询
SELECT po_num, ship_date FROM orders main
WHERE 10 >
(SELECT COUNT (DISTINCT ship_date)
FROM orders sub
WHERE sub.ship_date < main.ship_date)
AND ship_date IS NOT NULL
ORDER BY ship_date, po_num;
因为子查询产生的数取决于 main.ship_date(外部 SELECT 产生的一个值),所以该子查
询是相关的。因此,必须对外部查询考虑的每一行重新执行子查询。
该查询使用 COUNT 函数来将值返回到主查询。然后,ORDER BY 子句对数据进行排序。
查询找到并返回具有 10 个最新装运日期的 16 行,如下所示。
图: 查询结果
po_num ship_date
4745 06/21/1998
278701 06/29/1998
429Q 06/29/1998
8052 07/03/1998
B77897 07/03/1998
LZ230 07/06/1998
B77930 07/10/1998
PC6782 07/12/1998
DM354331 07/13/1998
S22942 07/13/1998
MA003 07/16/1998
W2286 07/16/1998
Z55709 07/16/1998
C3288 07/25/1998
KF2961 07/30/1998
W9925 07/30/1998
如果对大型表使用相关子查询(如图 1),那么应对 ship_date 列建立索引以提高性能。否
则,此 SELECT 语句效率降低,原因是它对表的每一行执行一次子查询。有关建立索引和
性能问题的信息,请参阅《GBase 8s 管理员指南》 和 GBase 8s 性能指南 。
然而,不能在 FROM 子句中使用相关子查询,如下列无效示例所示:
SELECT item_num, stock_num FROM items,
(SELECT stock_num FROM catalog
WHERE stock_num = items.item_num) AS vtab;
该示例中的子查询具有错误 -24138:
ALL COLUMN REFERENCES IN A TABLE EXPRESSION MUST REFER
TO TABLES IN THE FROM CLAUSE OF THE TABLE EXPRESSION.
数据库服务器发出该错误的原因是子查询中的 items.item_num 列还出现在外部查询的
Projection 子句中,但是内部查询的 FROM 子句仅指定catalog 表。错误消息文本中的术语
表表达式指的是 FROM 子句中的子查询返回的列值或表达式集合。而在 FROM 子句中,
只有不相关子查询才是有效的。