是否可以为引用主查询的子查询创建视图?

Is it possible to create a view for a subquery referring the main query?

如果有一个使用子查询的查询。基本上是这样的:

SELECT A.name, A.pk 
       array_to_string(array(SELECT B.name FROM b WHERE B.relA  = A.pk ),', ')    
FROM A;

基本上,它在 A 中创建一个从一对多关系到 B 的列。 (在我的例子中,A 是一个项目列表,B 包含与该项目相关的标签。查询为 A 中的每一行创建一个包含标签列表的列。)

由于现实世界的查询比较复杂,而且我不止一次需要子查询,所以我想从子查询(DRY)做一个视图。这是不可能的,因为 A.pk 只有在子查询 A 获取的主查询中的子查询时才知道。不知道子查询是否独立。所以我无法从独立版本创建视图:

CREATE VIEW bview AS SELECT B.b FROM B WHERE B.relA=A.pk;

给了我预期的:

ERROR:  missing FROM-clause entry for table "A"

有没有一种方法可以定义类似 "incomplete view" 的方法,它本身不执行,而是在不使用函数的情况下在主查询中完成子查询?

编辑:子查询中的 WHERE 子句不能替换为 JOIN 子句,因为它从外部查询中获取 A.pk

您可以在不引用 table A 的情况下创建一个简单视图,然后将其用作复杂查询各个部分的行源:

CREATE VIEW bview AS
    SELECT relA, string_agg(name, ', ') AS tags
    FROM b
    GROUP BY relA;

这可能看起来效率低下,因为如果您 运行 像这样没有限定的视图,那么所有 relA 的所有标签都会连接起来。但是,当您在具有限定条件的较大查询中使用视图时,将仅针对外部查询中要求的那些 relA 值评估视图。这是因为 the view is "merged" with the outer query by the planner.

所以你最终得到:

SELECT name, pk, tags
FROM A
JOIN bview ON relA = pk;