2010-10-27 6 views
8

Le schéma est le suivant:arbre d'impression avec CTE SQL

CREATE TABLE [Structure](
    [StructureId] [uniqueidentifier] NOT NULL, 
    [SequenceNumber] [int] NOT NULL, -- order for siblings, unique per parent 
    [ParentStructureId] [uniqueidentifier] NULL, 
CONSTRAINT [Structure_PK] PRIMARY KEY CLUSTERED 
(
    [StructureId] ASC 
) 
) ON [PRIMARY] 

ALTER TABLE [Structure] WITH CHECK ADD CONSTRAINT [Structure_FK1] 
FOREIGN KEY([ParentStructureId]) 
REFERENCES [Structure] ([StructureId]) 

Actuellement, je peux obtenir toutes les données logiques avec le CTE suivre, mais je voudrais l'imprimer directement une profondeur d'abord la mode.

WITH SCTE (StructureId, Level, Seq, ParentId) 
AS 
(
    SELECT StructureId, 0, SequenceNumber, [ParentStructureId] 
    FROM Structure 
    WHERE [ParentStructureId] IS NULL 
      AND StructureId = 'F6C5F016-1270-47C1-972F-349C32DFC92A' 

    UNION ALL 

    SELECT Structure.StructureId, Level + 1, SequenceNumber, ParentStructureId 
    FROM Structure 
    INNER JOIN SCTE ON SCTE.StructureId = Structure.ParentStructureId 
) 

SELECT * FROM SCTE 
ORDER BY Level, ParentId, Seq 

La sortie est la suivante (tronquée ici):

StructureId      Level Seq ParentId 
F6C5F016-1270-47C1-972F-349C32DFC92A 0 0 NULL 
D2E34429-401A-4A49-9E18-E81CCA0FB417 1 0 F6C5F016-1270-47C1-972F-349C32DFC92A 
0CC5E16C-9194-40CA-9F72-1CED2972D7CA 1 1 F6C5F016-1270-47C1-972F-349C32DFC92A 
1ECD1D30-EB85-42B0-969F-75794343E3B4 1 2 F6C5F016-1270-47C1-972F-349C32DFC92A 
EEC3A981-B790-4600-8CD1-F15972CD9230 2 0 0CC5E16C-9194-40CA-9F72-1CED2972D7CA 
4406F639-2F58-4918-A9EF-A4B0F379BEA0 2 1 0CC5E16C-9194-40CA-9F72-1CED2972D7CA 
FCAF7870-C606-4AA6-85EE-57B90B1B0CC3 2 2 0CC5E16C-9194-40CA-9F72-1CED2972D7CA 
855DF5FB-1593-4E5B-8EF9-3770B45F89D6 2 3 0CC5E16C-9194-40CA-9F72-1CED2972D7CA 
3D16DF32-C04F-49B4-B0D9-5BDC9104F810 2 4 0CC5E16C-9194-40CA-9F72-1CED2972D7CA 
A1084D00-0198-47D9-87E0-BB8234233F14 2 5 0CC5E16C-9194-40CA-9F72-1CED2972D7CA 
CE443C0D-376F-46EC-9914-32C6B7200DB1 2 6 0CC5E16C-9194-40CA-9F72-1CED2972D7CA 
0DEA587D-4FCF-414C-AD71-FB00829F8082 2 7 0CC5E16C-9194-40CA-9F72-1CED2972D7CA 
CC9FC8D3-254A-486B-8DC4-07E57627476C 2 0 1ECD1D30-EB85-42B0-969F-75794343E3B4 
215565CC-501F-4850-B8AE-5466DA5E6854 2 1 1ECD1D30-EB85-42B0-969F-75794343E3B4 
D4E6C8E5-5ADD-4AD1-B59B-1A672F66888A 2 2 1ECD1D30-EB85-42B0-969F-75794343E3B4 
796C65BF-4714-4DBF-A97A-2150DBE3098C 2 3 1ECD1D30-EB85-42B0-969F-75794343E3B4 
B39DEB9C-BE42-43B4-9C38-968399D7D1E2 2 4 1ECD1D30-EB85-42B0-969F-75794343E3B4 
6C2F70C6-1DA0-4E1A-BBC1-D7FCAFE6AFEE 2 0 D2E34429-401A-4A49-9E18-E81CCA0FB417 
75D7B43B-C971-46B4-BC42-58C3605ADD79 2 1 D2E34429-401A-4A49-9E18-E81CCA0FB417 
0B5AAAA0-A69F-431E-86BA-148444D7B1E6 2 2 D2E34429-401A-4A49-9E18-E81CCA0FB417 
CB3CF66B-D83A-45E2-953A-6F0CEE094F5B 2 3 D2E34429-401A-4A49-9E18-E81CCA0FB417 
1D5F69C3-F036-4667-BD75-A0DC1506DB6D 2 4 D2E34429-401A-4A49-9E18-E81CCA0FB417 
71B894F7-B9FC-44DE-AEDB-E6FA026A6082 2 5 D2E34429-401A-4A49-9E18-E81CCA0FB417 
F1DFA1E1-013B-449C-9D9D-14C64E75D418 2 6 D2E34429-401A-4A49-9E18-E81CCA0FB417 

Comme vous pouvez le voir, le résultat est « largeur d'abord », qui fait l'impression d'un arbre un peu impossible car il est maintenant.

Y at-il un moyen (il ya probablement un moyen trivial, mais mes compétences SQL sont extrêmement pauvres) pour obtenir la liste résultante au format «arbre d'impression convivial»? Je sais que je pourrais juste vider les résultats dans un programme et coder la sortie, mais comme un exercice je préférerais faire cela dans SQL lui-même.

Merci

Répondre

10

Edité après un commentaire. Vous pouvez ajouter le chemin à un nœud, et l'ordre sur celui-ci:

declare @t table (id int, parent int) 
insert @t (id, parent) values (1, null), (2,1), (3,2), (4,3), (5,null), (6,5) 

; with cte as (
    select id, parent 
    ,  cast(RIGHT(REPLICATE('0',12) + 
       CONVERT(varchar(12),id),12) as varchar(max)) Path 
    from @t 
    where parent is null 
    union all 
    select child.id, child.parent 
    ,  parent.Path + RIGHT(REPLICATE('0',12) + 
           CONVERT(varchar(12),child.id),12) as Path 
    from @t child 
    join cte parent 
    on  parent.id = child.parent 
) 
select * 
from cte 
order by 
     Path 

Ceci imprime la racine en premier, suivi par des feuilles dans l'ordre. Si votre identifiant peut être supérieur à 12 chiffres, augmentez le nombre dans les cas char(x).

+0

Je ne veux pas l'impression la plus profonde en premier. La racine doit imprimer en premier, comme un arbre. Je veux juste obtenir toutes les branches en premier ordre croissant, ainsi il peut être imprimé facilement sans traitement supplémentaire. – leppie

+0

Aussi, j'ai déjà la colonne 'Level' 'qui fait cela ... – leppie

+0

@leppie: Ok, répondre édité – Andomar

Questions connexes