Parent - requête sql enfant
-
05-07-2019 - |
Question
id parent_id
1 0
2 0
3 2
4 0
5 1
6 0
J'ai besoin d'une requête qui renverra des lignes parent (id_ parent = 0) suivies de ses lignes enfant:
- premier parent
- tous les enfants du premier parent
- deuxième parent
- tous les enfants du deuxième parent
- troisième parent
- quatrième parent
Résultat attendu: classé par identifiant
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 suivie de tous les enfants Mais cela me donne d'abord les parents, puis les enfants. J'ai besoin d'un parent et immédiatement de ses enfants.
Tout le monde peut aider?
La solution
Cela 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
Autres conseils
Si vous êtes dans SQL Server 2005+, vous pouvez utiliser un CTE récursif en vous assurant de conserver un champ que vous pouvez classer à 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
;