SQL SERVER 2005 新特性CTE

--1.指定临时命名的结果集,这些结果集称为公用表表达式 (CTE)。
--
2.该表达式源自简单查询,并且在 SELECT、INSERT、UPDATE 或 DELETE 语句的执行
--
范围内定义。
--
3.该子句也可用在 CREATE VIEW 语句中,作为该语句的 SELECT 定义语句的一部分。
--
4.公用表表达式可以包括对自身的引用。这种表达式称为递归公用表表达式。


use demo2
select * from student
go
--创建一个简单的CTE
--
统计学生表中的男女总人数
WITH StuReps(SEX, TotalReports) AS 
(
    
SELECT SEX, COUNT(*
    
FROM STUDENT AS e
    
WHERE SID IS NOT NULL
    
GROUP BY SEX
)
SELECT SEX, TotalReports 
FROM StuReps 
ORDER BY SEX;

--统计每个学生考试课程总数
with CurReps(SID,TotalSutudyCur)as 
(
 
select sid, count(curid) as TotalSutudyCur
 
from scorebook 
 
group by sid 
)
select sid,TotalSutudyCur
from   curReps
order by sid

GO
--统计考试课程总数大于2的考生信息
with CurReps(SID,TotalSutudyCur)as 
(
 
select sid , count(curid) as TotalSutudyCur
 
from scorebook 
 
group by sid 
)
select a.sid ,b.name,a.TotalSutudyCur
from   curReps as a,student as b
where  a.TotalSutudyCur>2 and a.sid=b.sid
order by a.sid
GO

select * from scorebook
go




 
--下面的语句将显示下列错误
--
无法绑定由多个部分组成的标识符 "e.score"。
--
在公用表表达式中存在一个字段名称为score
--
在要更新的scorebook表中也存在一个字段名称为score

with scoreReps(id,sname,cid,score)
as
(
select a.sid,a.name,b.curid,b.score
from student as a
inner join scorebook as b
on a.sid=b.sid
where a.sid is not null
)
update scorebook set e.score=e.score*0.5
from scorebook as e, scoreReps as f 
where  e.sid=f.id and f.sname='frj'

--修改后,执行成功.
with scoreReps(id,sname,cid,score2)
as
(
select a.sid,a.name,b.curid,b.score
from student as a
inner join scorebook as b
on a.sid=b.sid
where a.sid is not null
)
update scorebook set score=score*0.5
from scorebook as e, scoreReps as f 
where  e.sid=f.id and f.sname='frj'


--恢复原来的值
with scoreReps(id,sname,cid,score2)
as
(
select a.sid,a.name,b.curid,b.score
from student as a
inner join scorebook as b
on a.sid=b.sid
where a.sid is not null
)
update scorebook set score=score*2
from scorebook as e
join scoreReps as f 
on  e.sid=f.id and f.sname='frj'

--在CREATE VIEW 语句中,调用CTE;

IF OBJECT_ID ('CTETestView''view'IS NOT NULL
DROP VIEW CTETestView ;
GO
CREATE VIEW CTETestView
AS
with scoreReps(id,sname,cid,score2)
as
(
select a.sid,a.name,b.curid,b.score
from student as a
inner join scorebook as b
on a.sid=b.sid
where a.sid is not null
)
select * from scorereps
go

select * from ctetestview
go


--递归用法的练习
--
查找姓名为'LI'的书是从那个人手里借来的.
create table BorrowCommodity
(
 SID  
INT,
 SNAME 
NVARCHAR(20),
 BorrowFrom 
INT
)
GO
INSERT INTO BorrowCommodity values(1,'FRJ',NULL)
INSERT INTO BorrowCommodity values(2,'HLK',1)
INSERT INTO BorrowCommodity values(3,'LI',4)
INSERT INTO BorrowCommodity values(4,'WANG',2)

GO

WITH BorrowFromReps(ID)
AS
(
SELECT BorrowFrom 
from BorrowCommodity
where sname='LI'
union all
SELECT A.BorrowFrom
from BorrowCommodity as a,BorrowFromReps as b
where a.SID=b.ID
)
select a.* 
from BorrowCommodity as a ,BorrowFromReps as b
where a.SID=b.ID 
--OPTION (MAXRECURSION 3);
--
使用 MAXRECURSION 提示来将递归级别限制为3个,防止不合理的递归 CTE 进入无限循环。
--
默认最大递归级别为100个.

USE DEMO2
GO
begin transaction
go
DROP TABLE CURRICULUM
DROP TABLE SCOREBOOK
DROP TABLE STUDENT
GO

CREATE TABLE STUDENT
(
  SID 
NVARCHAR(10),
  
[NAME] NVARCHAR(20),
  SEX    
CHAR(2),
  AGE    
INT,
  ADDRESS 
NVARCHAR(50),
  
PRIMARY KEY(SID)
)
GO

CREATE TABLE CURRICULUM
(
 CURID   
NVARCHAR(10),
 CURNAME 
NVARCHAR(30),
 
PRIMARY KEY (CURID)
)
GO

CREATE TABLE SCOREBOOK
(
  CURID    
NVARCHAR(10REFERENCES CURRICULUM(CURID),
  SID      
NVARCHAR(10REFERENCES STUDENT(SID),
  SCORE    
INT,
  TESTDATE 
DATETIME NOT NULL DEFAULT (getdate()),
  
)

GO 

insert into student(sid,name,sex,age,address)values('1','frj','','18','hunan')
insert into student(sid,name,sex,age,address)values('2','hlk','','18','shichuan')
insert into student(sid,name,sex,age,address)values('3','wang','','18','hebe')
insert into student(sid,name,sex,age,address)values('4','li','','18','anhui')
insert into student(sid,name,sex,age,address)values('5','zhang','','18','zhejian')
insert into student(sid,name,sex,age,address)values('6','liu','','18','hunan')
insert into student(sid,name,sex,age,address)values('7','den','','18','shanghai')
insert into student(sid,name,sex,age,address)values('8','zhou','','18','guandon')
go
insert into CURRICULUM(curid,curname)  values('s1','语文')
insert into CURRICULUM(curid,curname)  values('s2','数学')
insert into CURRICULUM(curid,curname)  values('s3','英语')
insert into CURRICULUM(curid,curname)  values('s4','程序设计')
insert into CURRICULUM(curid,curname)  values('s5','数据结构')
insert into CURRICULUM(curid,curname)  values('s6','离散数学')
insert into CURRICULUM(curid,curname)  values('s7','网络技术')
insert into CURRICULUM(curid,curname)  values('s8','微机原理')
go

insert into SCOREBOOK(curid,sid,score)  values('s1','1',90)
insert into SCOREBOOK(curid,sid,score)  values('s2','1',80)
insert into SCOREBOOK(curid,sid,score)  values('s3','1',96)
insert into SCOREBOOK(curid,sid,score)  values('s1','2',70)
insert into SCOREBOOK(curid,sid,score)  values('s4','2',98)
insert into SCOREBOOK(curid,sid,score)  values('s5','2',90)
insert into SCOREBOOK(curid,sid,score)  values('s1','3',98)
insert into SCOREBOOK(curid,sid,score)  values('s3','3',89)
go
原文地址:https://www.cnblogs.com/furenjun/p/sql2005_cte.html