SELECT 语句中的子查询 / WHERE 子句中的子查询 |
相关子查询是引用不在其 FROM 子句中的列或表的子查询。该列可以在 Projection 子句或 WHERE 子句中。
通常,相关子查询会降低性能。建议使用表名或表别名限制子查询中的列名。从而除去与列所驻留的表相关的任何疑问。
图: 查询
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 产生的一个值),所以该子查询是相关的。因此,必须对外部查询考虑的每一行重新执行子查询。
图: 查询结果
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 性能指南 。
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 子句中,只有不相关子查询才是有效的。