2010-08-12 11 views
11

Ich habe eine Tabelle:Wie selbst JOIN rekursiv in SQL?

 
Series 
======== 
ID 
SeriesName 
ParentSeriesID 

Eine Reihe kann eine „root“ -Serie sein, (ParentSeriesID 0 oder null) oder es kann einen Elternteil hat. Eine Reihe kann auch mehrere Ebenen nach unten sein, d. H. Ihr Elternteil hat ein Elternteil, das ein Elternteil usw. hat.

Wie kann ich die Tabelle abfragen, um eine Serie nach ihrer ID und allen Nachkommen zu erhalten?

Bisher habe ich versucht:

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

Aber das gibt nur die erste Ebene der Kinder, ich den übergeordneten Knoten werden soll, und alle „downstream“ Knoten. Ich bin mir nicht sicher, wie ich von hier fortschreiten soll.

Antwort

13

Wenn Sie SQL Server verwenden 2005+, Sie können allgemeine Tabellenausdrücke verwenden

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 

Weitere:

Recursive Queries Using Common Table Expressions

+0

Ich habe Ihre Abfrage geändert, um es zum Laufen zu bringen, setzen Sie es in meine Bearbeitung zu Ihrer Frage. Danke für Ihre Hilfe! –

+0

Jede Möglichkeit, dies auf einer nicht ms SQL Server DB zu tun? Ich brauche einen Standardweg ohne CTE zu benutzen. –

+0

@goku_da_master - Kommt drauf an, was du meinst. Derselbe Code sollte für Postgres, Oracle und DB2 funktionieren. Gemeinsame Tabellenausdrücke sind Teil der SQL-Spezifikation und werden daher von mehreren Anbietern implementiert. Es klingt jedoch so, als würden Sie fragen, wie Sie dasselbe in einer Datenbank erreichen können, die CTEs wie MySQL oder MS Access nicht unterstützt. Die Antwort hängt vom Produkt ab. – Thomas

2

Nutzen Sie CTE Funktion verfügbar in slq Server 2005 an für recurisve Abfrage

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 

Sie können beispielsweise hier ansehen:

SQL SERVER – Simple Example of Recursive CTE

+0

CTE? Ich habe SQL 2005 –

+2

cte = gemeinsame Tabelle Ausdruck! – SwissCoder

5

ich die Arbeit von Thomas gerade verbessern. Wenn Sie die Tiefe der Hierarchie erhalten müssen und die Parent-ID hier erhalten, ist der Code.

Dies war fast das gleiche mit Thomas 'Arbeit.

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 

Das ist alles. Ich weiß, es ist zu spät, aber ich hoffe, dass jeder, der darauf trifft, ihnen helfen kann. Danke Thomas für den ursprünglichen Code. :)