关于PostgreSQL官方手册表函数示例的技术疑问咨询
PostgreSQL表函数示例疑问解答
先看官方手册中的示例代码:
CREATE TABLE foo (fooid int, foosubid int, fooname text); CREATE FUNCTION getfoo(int) RETURNS SETOF foo AS $$ SELECT * FROM foo WHERE fooid = $1; $$ LANGUAGE SQL; SELECT * FROM foo WHERE foosubid IN ( SELECT foosubid FROM getfoo(foo.fooid) z WHERE z.fooid = foo.fooid );
问题1:该嵌套SELECT语句与SELECT * FROM foo有何不同?实用价值是什么?
- 核心差异:
SELECT * FROM foo会返回表中所有记录;而带嵌套查询的语句只会返回满足关联条件的行——它会筛选出当前行的foosubid存在于「同fooid分组的子ID集合」中的记录。比如某行fooid=1,就会调用getfoo(1)拿到所有fooid=1的行,再检查当前行的foosubid是否在这些行的foosubid列表里。 - 实用价值:这是一种行级动态关联筛选,可用于找出同主ID分组内有重复子ID的记录;更泛化的场景是,当你需要基于当前行字段值动态调用表函数,并用函数返回结果作为筛选条件时,这种写法能实现精准的行级匹配逻辑。
问题2:getfoo(foo.fooid)如何获取foo.fooid的值?传入table.column这类参数时,函数是否总会遍历所有值?
- 取值逻辑:这是PostgreSQL的相关子查询特性,子查询里的
foo.fooid指的是外层主查询当前正在处理的那一行的fooid值。主查询每遍历一行foo表的记录,就会把当前行的fooid作为参数传入getfoo,得到对应结果集后再做IN判断。 - 执行次数:默认情况下,函数会针对外层查询的每一行执行一次(除非PostgreSQL查询优化器将其改写成JOIN形式来减少调用次数)。简单说,不是一次性传入所有值,而是随外层行遍历逐行调用。
内容的提问来源于stack exchange,提问作者okzoomer
相关产品推荐
相关产品推荐

