2010-08-12 4 views
11

I ont un tableau:Comment s'inscrire JOINT récursivement dans SQL?

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

Une série peut être une série "root", (ParentSeriesID est égal à 0 ou null) ou il peut avoir un parent. Une série peut également avoir plusieurs niveaux, par exemple son parent a un parent, qui a un parent, etc.

Comment puis-je interroger la table pour obtenir une série par son ID et toutes les séries descendant '?

Jusqu'à présent, j'ai essayé:

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

Mais cela ne retourne le premier niveau des enfants, je veux que le nœud parent et tous les noeuds « en aval ». Je ne suis pas sûr de savoir comment progresser d'ici.

Répondre

13

Si vous utilisez SQL Server 2005+, vous pouvez utiliser des expressions de table commune

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 

Pour en savoir plus:

Recursive Queries Using Common Table Expressions

+0

J'ai modifié votre requête pour la faire fonctionner, mettez-la dans mon edit à votre question. Merci de votre aide! –

+0

Tout moyen de le faire sur un serveur SQL non MS SQL? J'ai besoin d'un moyen plus standard sans utiliser de CTE. –

+0

@goku_da_master - Cela dépend de ce que vous voulez dire. Le même code devrait fonctionner correctement sur Postgres, Oracle et DB2. Les expressions de table communes font partie de la spécification SQL et sont donc implémentées par plusieurs fournisseurs. Cependant, il semble que vous demandiez comment obtenir la même chose sur une base de données qui ne supporte pas les CTE tels que MySQL ou MS Access. La réponse dépendra du produit. – Thomas

2

Faire usage de CTE fonction avaiable dans le serveur slq de 2005 pour la requête recurisve

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 

Vous pouvez voir par exemple ici:

SQL SERVER – Simple Example of Recursive CTE

+0

CTE? J'ai SQL 2005 –

+2

cte = expression de la table commune! – SwissCoder

5

Je ne font qu'accentuer le travail de Thomas. Si vous avez besoin d'obtenir la profondeur de la hiérarchie et d'obtenir le parentid, voici le code.

C'était presque la même chose avec le travail de 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 

C'est tout. Je sais qu'il est trop tard, mais j'espère que quiconque rencontrera cela pourra les aider. Merci Thomas pour le code original. :)