CTE(带语句)是否允许在PostgreSQL中消除公共子表达式?
我正在编写一个生成大型SQL表达式和复杂查询的系统。 为了我自己的理智,我让代码生成器与表达式一起使用,以简化代码并使其更具可读性它仍然产生的恐怖示例如下: 在某些地方,我希望重用复杂子表达式的结果任意次数,我想知道绑定表达式的计算次数,例如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 ...)
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会更好地发挥作用。请记住,联合涉及排序,这在计算上非常昂贵。谢谢,我的联合示例确实过于简单了——我只想选择一种简单的方法来多次重用查询。然而,这是我要记住的。