sql-server - Sql server中的Cte是执行一次还是每次被引用?

标签 sql-server common-table-expression

我有一张假 table

create table emp
(
  id int,
  name varchar,
  sal int
)

with cte1 as(
select * from emp where name like 'a%'
),  
cte2 as (
select * from cte1 where sal > 100
),
cte3 as (
select * from cte1 where id != 1223
)
select * from cte2
union all
select * from ct3

以这种方式使用 cte 是否保证 cte1、cte2、cte3 只会运行一次?

虽然我可以检查查询计划,但这是否能保证如果数据更改并且下次优化器决定以另一种方式执行此操作时行为不会改变?

最佳答案

“以这种方式使用 cte 是否保证 cte1、cte2、cte3 只会运行一次?”不会。您在此处的查询不会“运行”cte1一次,它将运行两次。这可以在查询的 query plan 中看到。在哪里可以看到 emp出现两次。

这是因为,在最后的 SELECT你引用两个 cte3cte2在最后的选择中。这两个引用 cte1 ,它又引用了 emp .因此,调用 cte3cte2导致对对象 emp 的 2 次调用.

从技术上讲,如果您愿意,可以将上面的内容重写为下面的内容;这可能会帮助您了解原因 emp被引用两次:

SELECT *
FROM (SELECT *
      FROM (SELECT *
            FROM emp
            WHERE [name] LIKE 'a%') AS cte1
      WHERE sal > 100) AS cte2
UNION ALL
SELECT *
FROM (SELECT *
      FROM (SELECT *
            FROM emp
            WHERE [name] LIKE 'a%') AS cte1
      WHERE id != 1223) AS cte3;

关于sql-server - Sql server中的Cte是执行一次还是每次被引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57807091/

相关文章:

c# - 将表从一个 SQL Server 高效更新到另一个相同的表结构

sql-server - 过程和存储过程sql server的区别?

sql-server - SQL Server,对多个表使用UNION ALL然后分页实现

sql-server - VS 2015 MSBuild 部署数据库项目错误

sql - 使用 CTE 时执行 CRUD 操作时对象名称无效 'Table'

postgresql - 与 PostgreSQL CTE 的一般并行性

使用交集除外或并集关系代数的 SQL Server 查询

postgresql - 如何对一组 PostgreSQL 查询进行基准测试?

sql - 使用 SQL 查询的 TreeView

sql - SQL子查询有多少种类型?