CTE递回
对于insert和delete,event中包含了插入/删除的记录的所有字段的值(太爽了。。)WITHCategoryInfoAS(
SELECT*FROMAWHEREid=1
UNIONALL
SELECTa.*FROMAASa,CategoryInfoASbWHEREa.PID=b.id
)
SELECT*FROMCategoryInfo
通用表表达式(CTEs)是SQLServer2005的一项新功效。它们相似于alias(如在SELECTT1.*FROMMyTableT1中),不外功效更加壮大。实质上,CTE是一个一时了局集,它仅仅存在于它产生的语句中。您能够在SELECT、INSERT、DELETE、UPDATE或CTEATEVIEW语句中创建一个CTE。CTE相似于派生表,但具有几项长处。
CTE的长处
与派生表分歧,CTE可以援用本人自己。假如您不用存储视图,您能够用一个CTE来取代它。在一个语句中,您还能够屡次援用CTE。使用CTE,您能够经由过程一个派生栏对了局举行分组。
之前,我曾写过有关原子和份子查询的文章。原子查询创建一个表,而份子查询创建在原子查询之上,供应明晰与反复使用。使用CTE也能够到达一样的目标。您能够将查询地区支解成可读的“块”,然后用这些块创建一个庞大的查询。实行递回查询是CTE最主要也是最壮大的功效。
创建CTE
CTE经由过程关头字WITH创建,其模板为:
WITHCTE_name[(column_name[,...n])]
AS
(CTE_query_specification)
假如在CTE界说中提到的栏称号是独一的,那末您能够不用给它们定名。不外,您一样也能够对它们从头定名。
上面的例子使用到SQLServer2005中的AdventureWorks样本数据库。这个数据库被高度规格化,因而必要几个毗连来汇合与雇员有关的信息。视图简化了这一操纵,但也搜集了一切有关雇员的信息,而您大概仅仅必要个中一部分材料。
AdventureWorks的雇员数据散布在几个表中;并且,雇员与司理被存储在统一个表中(HumanResources.Employee),而他们的姓名(及别的数据)则存储在Person.Contact表中,这使得这个成绩加倍庞大。
起首,我们创建一个恢复雇员姓名的CTE。
WITHcte_Employee
AS
(
SELECTe.EmployeeID,c.FirstName,c.MiddleName,c.LastName,
e.TitleASJobTitle,c.Phone,e.ManagerID
FROMHumanResources.EmployeeASe
INNERJOINPerson.ContactAScONc.ContactID=e.ContactID
)
然后,我们可从CTE当选择一栏或几栏,就像它是一个尺度的表或视图。
接着我们再进一步。我们必要雇员和他们司理的姓名,因而我们利用CTE两次,把它本身毗连起来。上面是完全的查询代码:
WITHcte_Employee
AS
(
SELECTe.EmployeeID,c.FirstName,c.MiddleName,c.LastName,
e.TitleASJobTitle,c.Phone,e.ManagerID
FROMHumanResources.EmployeeASe
INNERJOINPerson.ContactAScONc.ContactID=e.ContactID
)
SELECTE.FirstName+E.LastNameEmployee,
M.FirstName+M.LastNameManager
FROMcte_EmployeeASE
LEFTOUTERJOINcte_EmployeeASM
ONE.ManagerID=M.EmployeeID
限定:不克不及在一个语句中创建两个CTE。
总结
CTE是SQLServer2005的一项壮大而天真的功效。它使得SQLServer的可读性更强,更容易于办理,下降了查询的庞大水平。如上所述,您能够在一个SQLServer语句中屡次使用CTE。
两个cte同时利用例子:
withw_Produce_MadeOrderDetailas
(
select*,batch=(selectBatchfromProduce_MadeOrderwhereProduce_MadeOrder.MOID=Produce_MadeOrderDetail.MOID)fromProduce_MadeOrderDetail
),
CostMadeProuceas(
selectGID,Batch,1asLevelNumberfromCost_MetCostDetailAwhereA.MCIDin(selectUseIDfromCost_Prouduce_UsewhereType=物料投进andBatch=B20090911002)
andexists(select*fromw_Produce_MadeOrderDetailBwhereA.GID=B.GIDandA.Batch=B.Batch)
unionall
selecte.GID,e.Batch,f.LevelNumberfromCost_MetCostDetaileinnerjoin
(
selectc.UseID,d.LevelNumberfromCost_Prouduce_Usecinnerjoin
(
selecta.GID,a.Batch,b.LevelNumber+1asLevelNumberfromw_Produce_MadeOrderDetaila,
CostMadeProucebwherea.batch=b.batchanda.GID=b.GID
)donc.Batch=d.Batchwherec.Type=物料投进
)fone.MCID=f.UseIDwhereexists(select*fromw_Produce_MadeOrderDetailgwheree.GID=g.GIDande.Batch=g.Batch)
)
select*fromCostMadeProuce
你看出了作者的深度?深处半米!当初是冲那么多的大牛给他写序才买的,后来才发现无啥内容,作者也只是才用几年的新手,百花了几十两银子,再次感叹当今社会的虚伪与浮躁 需要注意的一点,也是我使用过程中发现的一个问题。在建立function->schema->table后,如果在现有的分区表上建立没有显式声明的聚集索引时,分区表会自动变为非分区表。这一点很让我纳闷。 having子句的作用是筛选满足条件的组,即在分组之后过滤数据,条件中经常包含聚组函数,使用having条件显示特定的组,也可以使用多个分组标准进行分组。 比如日志传送、比如集群。。。 相信各位对数据库和怎么样学习数据库都有一些经验和看法,也会有人走了一些弯路总结出自己的经验来,希望大家能把各自的看法和经验拿出来分享,给别人一份帮助,给自己一份快乐 如果我们从集合论(关系代数)的角度来看,一张数据库的表就是一组数据元的关系,而每个SQL语句会改变一种或数种关系,从而产生出新的数据元的关系(即产生新的表)。 而SQLServer如果能像Oracle一样可以为登陆分配如:5%的cpu,10%的内存。就可以解决这个漏洞。 换言之,只有在不断的失败中尝试成功,而关于失败的总结却是很少的 还不是性能有问题!否则面向对象的数据库早就实现了!建议使用CLR的地方一般是和应用的复杂程度或操作系统环境有很高的耦合度的场景。如你想构建复杂的算法,并且用到了大量的指针和高级数据模型。
页:
[1]