SQL中 with as 的用法——使用公用表表达式(CTE)
公用表表达式 (CTE) 可以认为是在单个 SELECT、INSERT、UPDATE、DELETE 或 CREATE VIEW 语句的执行范围内定义的临时结果集。CTE 与派生表类似,具体表现在不存储为对象,并且只在查询期间有效。与派生表的不同之处在于,CTE 可自引用,还可在同一查询中引用多次。
CTE 可用于:
创建递归查询。
在不需要常规使用视图时替换视图,也就是说,不必将定义存储在元数据中。 启用按从标量嵌套 select 语句派生的列进行分组,或者按不确定性函数或有外部访问的函数进行分组。
在同一语句中多次引用生成的表。
使用 CTE 可以获得提高可读性和轻松维护复杂查询的优点。查询可以分为单独块、简单块、逻辑生成块。之后,这些简单块可用于生成更复杂的临时 CTE,直到生成最终结果集。
可以在用户定义的例程(如函数、存储过程、触发器或视图)中定义 CTE。 CTE 的结构
CTE 由表示 CTE 的表达式名称、可选列列表和定义 CTE 的查询组成。定义 CTE 后,可以在 SELECT、INSERT、UPDATE 或 DELETE 语句中对其进行引用,就像引用表或视图一样。CTE 也可用于 CREATE VIEW 语句,作为定义 SELECT 语句的一部分。
CTE 的基本语法结构如下:
WITH expression_name [ ( column_name [,...n] ) ]
AS
( CTE_query_definition )
只有在查询定义中为所有结果列都提供了不同的名称时,列名称列表才是可选的。
运行 CTE 的语句为:
SELECT <column_list>
FROM expression_name
示例:
with s_name as
(
select s.name, sc.c,sc.grade from SQL Server student AS s,sc where s.s#=sc.s#
)
select * from s_name
在使用CTE时应注意如下几点:
1. CTE后面必须直接跟使用CTE的SQL语句(如select、insert、update等),否则,CTE将失效。
2. CTE后面也可以跟其他的CTE,但只能使用一个with,多个CTE中间用逗号(,)分隔。
3. 如果CTE的表达式名称与某个数据表或视图重名,则紧跟在该CTE后面的SQL语句使用的仍然是CTE,当然,后面的SQL语句使用的就是数据表或视图了。
4. CTE 可以引用自身(递归查询),也可以引用在同一 WITH 子句中预先定义的 CTE。不允许前向引用。
5. 不能在 CTE_query_definition 中使用以下子句:
(1)COMPUTE 或 COMPUTE BY
(2)ORDER BY(除非指定了 TOP 子句)
(3)INTO
(4)带有查询提示的 OPTION 子句
(5)FOR XML
(6)FOR BROWSE
6. 如果将 CTE 用在属于批处理的一部分的语句中,那么在它之前的语句必须以分号结尾
第二篇:sql中with_as的用法
SQL中使用WITH AS提高性能-使用公用表表达式(CTE)简化嵌套SQL
一.WITH AS的含义
WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会被整个SQL语句所用到。有的时候,是为了让SQL语句的可读性更高些,也有可能是在UNION ALL的不同部分,作为提供数据的部分。
特别对于UNION ALL比较有用。因为UNION ALL的每个部分可能相同,但是如果每个部分都去执行一遍的话,则成本太高,所以可以使用WITH AS短语,则只要执行一遍即可。如果WITH AS短语所定义的表名被调用两次以上,则优化器会自动将WITH AS短语所获取的数据放入一个TEMP表里,如果只是被调用一次,则不会。而提示materialize则是强制将WITH AS短语里的数据放入一个全局临时表里。很多查询通过这种方法都可以提高速度。
二.使用方法
先看下面一个嵌套的查询语句:
select * from person.StateProvince where CountryRegionCode in
(select CountryRegionCode from person.CountryRegion where Name like 'C%')
上面的查询语句使用了一个子查询。虽然这条SQL语句并不复杂,但如果嵌套的层次过多,会使SQL语句非常难以阅读和维护。因此,也可以使用表变量的方式来解决这个问题,SQL语句如下: declare @t table(CountryRegionCode nvarchar(3))
insert into @t(CountryRegionCode) (select CountryRegionCode from person.CountryRegion where Name like 'C%')
select * from person.StateProvince where CountryRegionCode
in (select * from @t)
虽然上面的SQL语句要比第一种方式更复杂,但却将子查询放在了表变量@t中,这样做将使SQL语句更容易维护,但又会带来另一个问题,就是性能的损失。由于表变量实际上使用了临时表,从而增加了额外的I/O开销,因此,表变量的方式并不太适合数据量大且频繁查询的情况。为此,在SQL Server 20xx中提供了另外一种解决方案,这就是公用表表达式(CTE),使用CTE,可以使SQL语句的可维护性,同时,CTE要比表变量的效率高得多。
下面是CTE的语法:
[ WITH <common_table_expression> [ ,n ] ]
<common_table_expression>::=
expression_name [ ( column_name [ ,n ] ) ]
AS
( CTE_query_definition )
现在使用CTE来解决上面的问题,SQL语句如下:
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 20xx在处理公用表表达式的方式上有所不同。
在使用CTE时应注意如下几点:
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的数据表
4. CTE 可以引用自身,也可以引用在同一 WITH 子句中预先定义的 CTE。不允许前向引用。
5. 不能在 CTE_query_definition 中使用以下子句:
(1)COMPUTE 或 COMPUTE BY
(2)ORDER BY(除非指定了 TOP 子句)
(3)INTO
(4)带有查询提示的 OPTION 子句
(5)FOR XML
(6)FOR BROWSE
6. 如果将 CTE 用在属于批处理的一部分的语句中,那么在它之前的语句必须以分号结尾,如下面的SQL所示:
declare @s nvarchar(3)
set @s = 'C%'
; -- 必须加分号
with t_tree as
(
select CountryRegionCode from person.CountryRegion where Name like @s
)
select * from person.StateProvince where CountryRegionCode in (select * from t_tree)
CTE除了可以简化嵌套SQL语句外,还可以进行递归调用,关于这一部分的内容将在下一篇文章中介绍。
第三篇:The review of This is water
这个评论是水
本文是发人深省的教我们学会思考的老鱼和幼鱼的故事,不在自己的直接经验的和以自我为中心的。作者阐述了我们开始相信我们在浩如烟海的文本世界的中心,自动和无意识的,然后他告诉我们如何避免这种情况。
我们不能否认我们的成年生活是乏味和令人沮丧的,因为我们不得不奔波的低工资的斗争,我们必须承受太多的压力来自工作和家庭,我们崇拜金钱和不觉得我们有足够的……听起来很糟糕,这些不良情绪,导致大量的投诉,然后我们责备别人对我们的困境。我们生活在自制的笼子里,但我们是并列的,渴望获得自由。作者认为,真正的自由应该注意,和意识,纪律,和努力,能够真正地关心其他人,为他们的牺牲,在这一点上,坦率地说,我不同意了。我们人类是社会群体。我们应该学会理解他人,而不是拒绝他们,爱他们。
从我自己的经验,我周围的人,包括我,就像作者所描述的,我们大多数人不知道奋斗的意义,我们不知道我们应该在我们的社会中扮演的角色,我们看不到未来的出口。我们应该从明智的关键。显然,这是不可想象的难做,保持意识清醒而活着,一天又一天。但是,我们必须做出改变,从现在开始。
这个评论是水
《这是水》这篇文章是由。。。。。。在故事的开头,作者以小鱼和老鱼的一段简单的对话,引出一个简单却令人深省的话题,教我们学会思考的老鱼和幼鱼的故事,不在自己的直接经验的和以自我为中心的。作者阐述了我们开始相信我们在浩如烟海的文本世界的中心,自动和无意识的,任何事情完全依赖于自己的本能,不能学会去思考其它不让人厌烦痛苦的因素,随后,作者又告诉我们如何避免这种情况。
作者列举了许多我们成年人日常生活中一些最简单的例子,我们不能否认我们的成年生活是乏味和令人沮丧的,因为我们不得不奔波的低工资的斗争,我们必须承受太多的压力来自工作和家庭,我们崇拜金钱和不觉得我们有足够的……听起来很糟糕,这些不良情绪,我们责备别人对我们的困境。我们生活在自制的笼子里,但我们是并列的,渴望获得自由。作者认为,真正的自由应该注意,和意识,纪律,和努力,能够真正地关心其他人,为他们的牺牲。我们人类是社会群体。我们应该学会理解他人,学会专注思考,我们就会发现许多事情会有其它选择,最真的东西是我们能够完全掌握自己要如何去看待事情。
在日常生活中,我们经常凭借自己的第一印象对我们所见到的人和事下定论,可是随着时间的推移,慢慢的我们对其了解之后便会发现他们并不是像我们初次见面那样,正如一句名言所说:生活中不是缺少美,只是缺少发现美得眼睛,换言之,我们应该换个角度去看问题。此外,从我自己的经验,我周围的人,包括我,
就像作者所描述的,我们大多数人不知道奋斗的意义,我们不知道我们应该在我们的社会中扮演的角色,我们看不到未来的出口。我们应该从明智的关键。显然,这是不可想象的难做,保持意识清醒而活着,意识我们生命中什么是真实的、必要的,总是围绕着我们却难以发现。因此,我们必须做出改变,必须时刻提醒自己,从现在开始。
因此,通过这篇文章,我们应该学会思考问题,拥有一双发现美得眼睛,这样我们才能获得真正教育中的真正价值。