with as 的优点
如果WITH AS
短语所定义的表名被调用两次以上,则优化器会自动将WITH AS
短语所获取的数据放入一个TEMP表
里,如果只是被调用一次,则不会。
而提示materialize
则是强制将WITH AS
短语里的数据放入一个全局临时表里。很多查询通过这种方法都可以提高速度。
例子
with cr as ( select CountryRegionCode from person.CountryRegion where Name like 'C%' ) select * from person.StateProvince where CountryRegionCode in (select * from cr)
其中cr是一个公用表表达式,该表达式在使用上与表变量类似,只是SQL Server 2005在处理公用表表达式的方式上有所不同。
注意
1 . CTE后面必须直接跟使用CTE的SQL语句(如select、insert、update等),否则,CTE将失效。如下面的SQL语句将无法正常使用CTE:
with cr as ( select CountryRegionCode from person.CountryRegion where Name like 'C%' ) select * from person.CountryRegion -- 应将这条SQL语句去掉 -- 使用CTE的SQL语句应紧跟在相关的CTE后面 -- select * from person.StateProvince where CountryRegionCode in (select * from cr)
2 . CTE后面也可以跟其他的CTE,但只能使用一个with,多个CTE中间用逗号(,)分隔,如下面的SQL语句所示:
with cte1 as ( select * from table1 where name like 'abc%' ), cte2 as ( select * from table2 where id > 20 ), cte3 as ( select * from table3 where price < 100 ) select a.* from cte1 a, cte2 b, cte3 c where a.id = b.id and a.id = c.id
3 .如果CTE的表达式名称与某个数据表或视图重名,则紧跟在该CTE后面的SQL语句使用的仍然是CTE,当然,后面的SQL语句使用的就是数据表或视图了,如下面的SQL语句所示:
-- table1是一个实际存在的表 with table1 as ( select * from persons where age < 30 ) select * from table1 -- 使用了名为table1的公共表表达式 select * from table1 -- 使用了名为table1的数据表
。。。。。。