/ / Jak sam łączyć się rekurencyjnie w SQL? - sql, sql-server-2005, tsql, dane hierarchiczne

Jak samodzielnie połączyć JOIN rekurencyjnie w SQL? - sql, sql-server-2005, tsql, dane hierarchiczne

Mam stół:

Seria ======== ID SeriesName ParentSeriesID

Seria może być serią „root” (ParentSeriesID ma wartość 0 lub null) lub może mieć rodzica. Seria może być także o kilka poziomów niższa, tj. Jej rodzic ma rodzica, który ma rodzica itp.

Jak mogę wysłać zapytanie do tabeli, aby uzyskać serię według jej „ID i WSZYSTKICH potomków”?

Do tej pory próbowałem:

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

Ale to tylko zwraca pierwszy poziom dzieci, chcę węzeł nadrzędny i wszystkie węzły „niższego rzędu”. Nie jestem pewien, jak stąd postępować.

Odpowiedzi:

13 dla odpowiedzi nr 1

Jeśli używasz SQL Server 2005+, możesz użyć wyrażeń wspólnej tabeli

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

Więcej informacji:

Zapytania rekursywne przy użyciu typowych wyrażeń tabel


5 dla odpowiedzi nr 2

Po prostu wzbogacam pracę Thomasa. Jeśli chcesz uzyskać głębię hierarchii i uzyskać rodzicielstwo tutaj, to kod.

To było prawie to samo z pracą Thomasa ”.

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

To wszystko. Wiem, że jest za późno, ale mam nadzieję, że każdy, kto się z tym spotka, może im pomóc. Dzięki Thomas za oryginalny kod. :)


2 dla odpowiedzi nr 3

Zrobić użytek z CTE funkcja dostępna w serwerze slq 2005 i późniejszym dla zapytania rekurencyjnego

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

Możesz zobaczyć przykład tutaj:

SQL SERVER - prosty przykład rekurencyjnego CTE