【问题标题】:Is it possible to create a view for a subquery referring the main query?是否可以为引用主查询的子查询创建视图?
【发布时间】:2023-03-05 09:23:02
【问题描述】:

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

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

【问题讨论】:

  • 或者你可以使用 CREATE VIEW bview AS SELECT A.pk, B.b FROM B JOIN A ON B.relA = A.pk;它:SELECT * FROM bview WHERE <where clause>
  • @RomanTkachuk 这不一样,因为它在子查询中创建了一个新的关系。但它应该从主查询中获取A.pk。我在 Q 中添加了 n 个解释。

标签: postgresql subquery sql-view


【解决方案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;

【讨论】:

  • 这是一个有趣的方法。我会试一试并报告结果。
猜你喜欢
  • 1970-01-01
  • 2014-01-07
  • 2011-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多