如何在SQL中递归地自连接?

如何在SQL中递归地自连接?,sql,sql-server-2005,tsql,hierarchical-data,Sql,Sql Server 2005,Tsql,Hierarchical Data,我有一张桌子: Series ======== ID SeriesName ParentSeriesID 但这只返回第一级子节点,我想要父节点和所有下游节点。我不知道如何从这里取得进展 使用slq server 2005及以后版本中可用的CTE功能进行递归查询 USE AdventureWorks GO WITH Emp_CTE AS ( SELECT EmployeeID, ContactID, LoginID, ManagerID, Title, BirthDate FROM HumanRe

我有一张桌子:

Series ======== ID SeriesName ParentSeriesID 但这只返回第一级子节点,我想要父节点和所有下游节点。我不知道如何从这里取得进展

使用slq server 2005及以后版本中可用的CTE功能进行递归查询

USE AdventureWorks
GO
WITH Emp_CTE AS (
SELECT EmployeeID, ContactID, LoginID, ManagerID, Title, BirthDate
FROM HumanResources.Employee
WHERE ManagerID IS NULL
UNION ALL
SELECT e.EmployeeID, e.ContactID, e.LoginID, e.ManagerID, e.Title, e.BirthDate
FROM HumanResources.Employee e
INNER JOIN Emp_CTE ecte ON ecte.EmployeeID = e.ManagerID
)
SELECT *
FROM Emp_CTE
GO
您可以在此处查看示例:


如果您使用的是SQL Server 2005+,则可以使用公共表表达式

With Family As 
( 
Select s.ID, s.ParentSeriesId, 0 as Depth
From Series s
Where ID = @ParentID 
Union All 
Select s2.ID, s2.ParentSeriesId, Depth + 1
From Series s2
    Join Family 
        On Family.ID = s2.ParentSeriesId 
) 
Select *
From Family 
更多信息:


我只是加强了托马斯的工作。如果需要获取层次结构的深度并获取parentid,下面是代码

托马斯的作品也是如此

With Family As 
( 
    Select s.ID, s.ParentSeriesId, 0 as Depth
    From Series s
    Where ID = @ParentID <--- this was removed if you intend to get all hierarchy of the record. You can retain this if you want
  Union All 
     Select s2.ID, s2.ParentSeriesId < --- change to **Family.ParentID**, Depth + 1
     From Series s2
     Join Family 
         On Family.ID = s2.ParentSeriesId 
) 
 Select *
 From Family 

就这些。我知道为时已晚,但我希望任何遇到这种情况的人都能帮助他们。感谢Thomas提供原始代码:

我修改了您的查询以使其正常工作,并将其放入我对您的问题的编辑中。谢谢你的帮助!有没有办法在非ms sql server数据库上执行此操作?“我需要一种更标准的方式而不使用CTE。@小悟空大师-取决于你的意思。同样的代码应该可以在Postgres、Oracle和DB2上正常工作。公共表表达式是SQL规范的一部分,因此由多个供应商实现。但是,听起来您在问如何在不支持CTE(如MySQL或MS Access)的数据库上实现同样的功能。答案将取决于product.cte=通用表表达式!
With Family As 
( 
    Select s.ID, s.ParentSeriesId, 0 as Depth
    From Series s
    Where ID = @ParentID <--- this was removed if you intend to get all hierarchy of the record. You can retain this if you want
  Union All 
     Select s2.ID, s2.ParentSeriesId < --- change to **Family.ParentID**, Depth + 1
     From Series s2
     Join Family 
         On Family.ID = s2.ParentSeriesId 
) 
 Select *
 From Family