Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
CTE(带语句)是否允许在PostgreSQL中消除公共子表达式?_Postgresql_Common Table Expression - Fatal编程技术网

CTE(带语句)是否允许在PostgreSQL中消除公共子表达式?

CTE(带语句)是否允许在PostgreSQL中消除公共子表达式?,postgresql,common-table-expression,Postgresql,Common Table Expression,我正在编写一个生成大型SQL表达式和复杂查询的系统。 为了我自己的理智,我让代码生成器与表达式一起使用,以简化代码并使其更具可读性它仍然产生的恐怖示例如下: 在某些地方,我希望重用复杂子表达式的结果任意次数,我想知道绑定表达式的计算次数,例如 WITH ... AS <DoSetup>, intermediate AS <ComplexQuery> SELECT a, b FROM (SELECT * FROM intermediate WHERE ...)

我正在编写一个生成大型SQL表达式和复杂查询的系统。 为了我自己的理智,我让代码生成器与表达式一起使用,以简化代码并使其更具可读性它仍然产生的恐怖示例如下:

在某些地方,我希望重用复杂子表达式的结果任意次数,我想知道绑定表达式的计算次数,例如

WITH ... AS <DoSetup>,
 intermediate AS <ComplexQuery>
SELECT a, b FROM 
    (SELECT * FROM intermediate WHERE ...)
    UNION
    (SELECT * FROM intermediate WHERE ...)

如果在此表达式中对ComplexQuery求值两次,是否有方法以只对其求值一次的方式重写该表达式?我已经研究过创建临时视图,但这似乎会在每次访问时重新评估子查询。

当您使用CTE时,我很确定它不会像使用视图时那样每次都重新执行子查询。它应该对查询求值一次并多次引用它。如果运行explain计划,它将显示只访问一次基表

我不是这方面的权威,我相信如果我读错了,会有人纠正我

除此之外,如果你上面的例子是一个相关的例子,你也许可以通过一个简单的OR条款来避免联合反对CTE。例如,如果它看起来像这样:

select * from intermediate where a = 1 and b < 50
union
select * from intermediate where a >= 0 and c > 99
您可以简单地将其改写为:

select *
from intermediate
where
  (a = 1 and b < 50) or
  (a >= 0 and c > 99)

再一次,也许你的例子过于简单化了,但我确实看到了很多——工会作为一个or会更好地发挥作用。请记住,联合涉及排序,这在计算上非常昂贵。

谢谢,我的联合示例确实过于简单了——我只想选择一种简单的方法来多次重用查询。然而,这是我要记住的。