--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 ISNOTNULL GROUPBY SEX ) SELECT SEX, TotalReports FROM StuReps ORDERBY SEX; --统计每个学生考试课程总数 with CurReps(SID,TotalSutudyCur)as ( select sid, count(curid) as TotalSutudyCur from scorebook groupby sid ) select sid,TotalSutudyCur from curReps orderby sid GO --统计考试课程总数大于2的考生信息 with CurReps(SID,TotalSutudyCur)as ( select sid , count(curid) as TotalSutudyCur from scorebook groupby sid ) select a.sid ,b.name,a.TotalSutudyCur from curReps as a,student as b where a.TotalSutudyCur>2and a.sid=b.sid orderby 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 innerjoin scorebook as b on a.sid=b.sid where a.sid isnotnull ) 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 innerjoin scorebook as b on a.sid=b.sid where a.sid isnotnull ) 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 innerjoin scorebook as b on a.sid=b.sid where a.sid isnotnull ) 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; IFOBJECT_ID ('CTETestView', 'view') ISNOTNULL DROPVIEW CTETestView ; GO CREATEVIEW CTETestView AS with scoreReps(id,sname,cid,score2) as ( select a.sid,a.name,b.curid,b.score from student as a innerjoin scorebook as b on a.sid=b.sid where a.sid isnotnull ) select*from scorereps go select*from ctetestview go --递归用法的练习 --查找姓名为'LI'的书是从那个人手里借来的. createtable BorrowCommodity ( SID INT, SNAME NVARCHAR(20), BorrowFrom INT ) GO INSERTINTO BorrowCommodity values(1,'FRJ',NULL) INSERTINTO BorrowCommodity values(2,'HLK',1) INSERTINTO BorrowCommodity values(3,'LI',4) INSERTINTO BorrowCommodity values(4,'WANG',2) GO WITH BorrowFromReps(ID) AS ( SELECT BorrowFrom from BorrowCommodity where sname='LI' unionall 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个.