当前位置: 首页 > 科技观察

SQL中递归问题详解

时间:2023-03-15 23:44:59 科技观察

递归查询原理SQLServer中的递归查询是通过CTE(表表达式)实现的。至少包含两个查询,第一个查询是一个定点成员,它只是一个返回有效表的查询,用作递归的基点或锚点;第二个查询称为递归成员,使得称为递归成员的查询是触发对CTE名称的递归引用。从逻辑上讲,CTE名称的内部应用可以理解为前面查询的结果集。递归查询的终止条件递归查询没有明确的递归终止条件,只有在第二次递归查询返回空结果集或超过递归次数的最大限制时才停止递归。引用递归次数上限的方法是使用MAXRECURION。递归查询的优点是效率高,在大量数据集下速度比程序查询要快。递归的常见形式WITHCTEAS(SELECTcolumn1,column2...FROMtablenameWHEREconditionsUNIONALLSELECTcolumn1,column2...FROMtablenameINNERJOINCTEONconditions)递归查询示例创建测试数据,有一张雇员表Employee,ManagerID是UserID的父节点,这是一个很简单的层次模型。USESQL_RoadGOCREATETABLEEmployee(UserIDINT,ManagerIDINT,NameNVARCHAR(10))INSERTINTOdbo.EmployeeSELECT1,-1,N'Boss'UNIONALLSELECT11,1,N'A1'UNIONALLSELECT12,1,N'A2'UNIONALLSELECT13,1,N'A3'UNIONALL11SELECT,111,N'B1'UNIONALLSELECT112,11,N'B2'UNIONALLSELECT121,12,N'C1'查询Employee表中的数据查询每个User的直接上级ManagerWITHCTEAS(SELECTUserID,ManagerID,Name,NameASManagerNameFROMdbo.EmployeeWHEREManagerID=-1UNIONALLSELECTc.UserID,c.ManagerID,c.Name,p.NameASManagerNameFROMCTEPINNERJOINdbo.EmployeecONp.UserID=c.ManagerID)SELECTUserID,ManagerID,Name,ManagerNameFROMCTE结果如下:我们来解读一下上面的代码1,查询ManagerID=-1,为根节点,这是递归查询的起点。2、迭代公式就是UNIONALL下面的查询语句。CTE是在查询语句中调用的,查询语句是CTE的组成部分,即“调用自己”,这就是递归的本质。所谓迭代就是每次递归调用上一次查询的结果集,而UNIONALL就是每次都合并结果集。3.迭代公式使用上一次查询返回的结果集执行特定的查询,直到CTE返回NULL或达到最大迭代次数。默认值为32。最终的结果集是迭代公式返回的结果集的并集。联合由UNIONALL子句定义,只能使用UNIONALL查询路径。下面我们通过层级查询从子节点到父节点的PATH,我们对上面的代码稍作修改:WITHCTEAS(SELECTUserID,ManagerID,Name,CAST(NameASNVARCHAR(MAX))ASLPathFROMdbo.EmployeeWHEREManagerID=-1UNIONALLSELECTc.UserID,c。ManagerID,c.Name,p.LPath+'->'+c.NameASLPathFROMCTEPINNERJOINdbo.EmployeecONp.UserID=c.ManagerID)SELECTUserID,ManagerID,Name,LPathFROMCTE其中CAST(NameASNVARCHAR(MAX))设置Name的长度最大,以防止字段太长而超过字段长度。具体结果如下:以上是对递归查询的一些知识的介绍。你可以自己试验一下。一般情况下,受访者在面试过程中往往会受到考察。希望能帮到大家~