正如公认的正确答案所说,with 子句在每个 CTE 链中仅使用一次。但是,为了完整起见,我想补充一下它不会阻止您嵌套 CTE。
如果cte2使用cte1,cte3使用cte2等,则CTE之间的依赖链是线性的,表示为with有3个CTE。相反,如果cte2 不需要cte1 并且两者都只在cte3 中需要,则应考虑将它们嵌套在cte3 (with cte3 as (with cte1 as (...), cte2 as (...) select...)) 的定义下。
然后,CTE 的语法反映了 CTE 之间的依赖关系树,并从字面上可视化了部分数据集的范围,这可以提高可读性并防止范围泄漏错误。并非所有数据库供应商都支持它,但 Postgres 支持。
Example:
with cte1(id,capital) as (
values(1,'Prague'),(2,'Bratislava')
), cte2(id,code) as (
with cte2inner1(id,code) as (
values(1,'CZ'),(2,'SK')
), cte2inner2(id,country) as (
values(1,'Czech Republic'),(2,'Slovakia')
)
select id,country from cte2inner1 join cte2inner2 using (id)
)
select *
from cte1 join cte2 using (id)
--join cte2inner1 not possible here