2009-10-22 12 views
2
id parent_id 
1 0 
2 0 
3 2 
4 0 
5 1 
6 0 

je besoin d'une requête qui renvoie des lignes mères (id_parent = 0), suivi par ses lignes enfants:Parent - requête sql enfant

  1. premier parent
  2. tous les enfants du premier parent
  3. second parent
  4. tous les enfants de deuxième parent
  5. troisième parent
  6. quatrième parent

Résultat attendu: id ordonnée par

id parent_id 
------------------------------------------- 
1 0 (first parent) 
5 1  (all children of first parent) 
2 0 second parent 
3 2  (all children of second parent) 
4 0 third parent 
6 0 fourth parent 

Je peux utiliser l'union des parents, suivi par tous Childs Mais cela me donne les parents d'abord, puis les enfants. J'ai besoin de parent et immédiatement ses enfants.

Quelqu'un peut-il aider?

+0

Quelle base de données utilisez-vous? –

+0

J'utilise SQL Server 2005 – kheya

Répondre

0

Ceci peut être accompli en utilisant deux tables temporaires et trois variables.

 
CREATE TABLE #Parents 
(
RowId bigint identity(1,1), 
Id bigint 
)

CREATE TABLE #Results ( RowId bigint identity(1,1), Id bigint, ParentId bigint )

DECLARE @Count1 bigint DECLARE @Count2 bigint DECLARE @ParentId bigint

INSERT INTO #Parents SELECT Id FROM MyTable WHERE ParentId = 0 ORDER BY Id

SET @Count1 = 0 SELECT @Count2 = MAX(RowId) FROM #Parents

WHILE @Count1 < @Count2 BEGIN SET @Count1 = @Count1 +1 SELECT @ParentId = Id FROM #Parents WHERE RowId = @Count1 INSERT INTO #Results (Id, ParentId) VALUES (@Count1, 0) INSERT INTO #Results (Id, ParentId) SELECT ID, ParentId FROM MyTable WHERE ID = @Count1 ORDER BY Id END

SELECT Id, ParentId FROM #Results ORDER BY RowId

DROP TABLE #Results DROP TABLE #Parents

3

Si vous utilisez SQL Server 2005+, vous pouvez utiliser un CTE récursif, en veillant à conserver un champ que vous pouvez commander à la fin.

Essayez ceci:

declare @t table (id int, parent_id int) 
insert @t 
select 1,0 
union all select 2,0 
union all select 3,2 
union all select 4,0 
union all select 5,1 
union all select 6,0 
; 

with tree as (
select t.*, convert(varbinary(max),t.id) as ordered 
from @t t 
where parent_id = 0 
union all 
select t.*, ordered + convert(varbinary(max),t.id) 
from tree base 
join 
@t t 
on t.parent_id = base.id 
) 
select * 
from tree 
order by ordered 
; 
+0

Cela ne fonctionne pas sur mon exemple de table Pouvez-vous écrire la requête qui donne la sortie que j'ai spécifiée ci-dessus comme résultat attendu? Merci – kheya

+0

Je veux dire que le CTE me donne d'abord toutes les lignes parentes. Alors tous les enfants. Pas le premier parent puis ses enfants, suivi par le deuxième parent et ses enfants et ainsi de suite – kheya

+0

Je cherche exactement le résultat utilisé pour afficher ce post et ses commentaires. Commentaire du parent puis ses réponses (enfants) puis un autre commentaire et ses réponses. Les réponses sont les commentaires des enfants sur les parents. – kheya

Questions connexes