如何在SQL中递归地进行self JOIN?

问题描述 投票:0回答:3

我有一张桌子:

系列
========
ID
系列名称
父系列ID

一个系列可以是一个“根”系列(

ParentSeriesID
为0或空),或者它可以有一个父级。一个系列也可以向下几个级别,即它的父级有一个父级,它有一个父级,等等

如何查询表以通过 ID 和所有后代系列获取系列?

到目前为止我已经尝试过:

 SELECT child.*
 FROM Series parent JOIN Series child ON child.ParentSeriesID = parent.ID
 WHERE parent.ID = @ParentID

但这只返回第一级子节点,我想要父节点,以及所有“下游”节点。我不知道如何从这里取得进展。

sql sql-server-2005 tsql hierarchical-data
3个回答
15
投票

如果您使用的是 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 

了解更多:

使用公用表表达式的递归查询


5
投票

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

这与 Thomas 的工作几乎相同。

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 

仅此而已。我知道为时已晚,但我希望任何遇到这种情况的人都可以帮助他们。感谢托马斯提供原始代码。 :)


2
投票

利用 SQL 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 – 递归 CTE 的简单示例

© www.soinside.com 2019 - 2024. All rights reserved.