WITH RECURSIVE
cte1 AS (...) -- can still be non-recursive
, cte2 AS (SELECT ...
UNION ALL
SELECT ...) -- recursive term
, cte3 AS (...)
SELECT ... FROM cte3 WHERE ...
正如公认的正确答案所说,with子句在每个CTE链中只使用一次。但是,为了完整起见,我想添加 * 它不会阻止您嵌套CTE *。 如果cte2使用cte1,cte3使用cte2等,则CTE之间的相关性链是线性的,并且其被表示为具有3个CTE的with。相反,如果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
With EmpCount1(DeptName,TotalEmployees)
as
(
Select DeptName, COUNT(*) as TotalEmployees
from Tbl_EmpDetails
join Tbl_Dept Dept
on Tbl_EmpDetails.DeptId = Dept.DeptId
WHERE DeptName IN ('BI','DOTNET')
group by DeptName
),
EmpCount2(DeptName,TotalEmployees)
as
(
Select DeptName, COUNT(*) as TotalEmployees
from Tbl_EmpDetails
join Tbl_Dept Dept
on Tbl_EmpDetails.DeptId = Dept.DeptId
WHERE DeptName IN ('JAVA','AI')
group by DeptName
)
Select * from EmpCount1
UNION
Select * from EmpCount2
4条答案
按热度按时间6yoyoihd1#
在顶部使用关键字
WITH
once。如果任何公用表表达式(CTE)是递归的(rCTE),则必须在顶部添加关键字RECURSIVE
*once *,即使并非所有CTE都是递归的:本手册:
如果指定了
RECURSIVE
,则允许SELECT
子查询按名称引用自身。大胆强调我的观点。更有见地的是:
RECURSIVE
的另一个效果是WITH
查询不需要排序:查询可以引用列表中较后的另一个查询。(然而,循环引用或相互递归不被实现。)如果没有RECURSIVE
,WITH
查询只能引用WITH
列表中较早的兄弟WITH
查询。再次加粗强调mine。意思是当使用了
RECURSIVE
关键词时,WITH
子句的顺序是 * 无意义的 *。顺便说一句,由于示例中的
cte1
和cte2
没有在外部SELECT
中引用,并且它们本身是普通的SELECT
命令(没有附带影响),因此它们永远不会被执行(除非在cte3
中引用)。mo49yndu2#
是的。你不用重复
WITH
。你只用一个逗号:And:仅对字符串常量和日期常量使用单引号。不要对列别名使用单引号。无论如何,CTE名称都不允许使用单引号。
yxyvkwin3#
正如公认的正确答案所说,
with
子句在每个CTE链中只使用一次。但是,为了完整起见,我想添加 * 它不会阻止您嵌套CTE *。如果
cte2
使用cte1
,cte3
使用cte2
等,则CTE之间的相关性链是线性的,并且其被表示为具有3个CTE的with
。相反,如果cte2
不需要cte1
,并且两者都只在cte3
中需要,则应考虑将它们嵌套在cte3
的定义下(with cte3 as (with cte1 as (...), cte2 as (...) select...)
)的数据。CTE的语法反映了CTE之间的依赖关系树,并从字面上可视化了部分数据集的作用域,这可以提高可读性并防止作用域泄漏错误。不是所有的数据库供应商都支持它,但Postgres支持。
Example:
cgvd09ve4#
问题原因:在这里,你不必使用多个WITH子句来合并Multiple CTE。
解决方案:可以在SQL中使用单个WITH子句创建多个公用表表达式。使用单个WITH子句创建两个不同的CTE,并以逗号分隔以创建多个CTE。
使用单个样品对多个CTE进行采样
这是使用单个With子句创建多个公用表表达式的示例语法。