是否可以为引用主查询的子查询创建视图?
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;
如果有一个使用子查询的查询。基本上是这样的:
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;