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

时间:2017-02-05 12:41:19

标签: postgresql subquery sql-view

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

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"

有没有办法定义类似于"不完整的视图",这不是自己执行的,而是在不使用函数的情况下完成子查询的主查询中?

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

1 个答案:

答案 0 :(得分:1)

您可以创建一个简单的视图,而无需引用表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;