2010-08-17 2 views
1

je une grande requête pour des performances liées à SQL Server 2005.J'ai une grande requête pour des performances liées à SQL Server 2005

J'ai données comme celui-ci

id parentId 
1 null 
2 1 
3 1 
4 2 
5 4 
6 3 

Je veux l'ordre du dossiers de filleuls avec parentId et id sage comme

id Order 
1 1 
2 2 
4 3 
5 4 
3 5 
4 6 

Je ne veux pas faire une boucle utiliser, car la boucle crée le problème si grand nombre de lignes. S'il vous plaît donnez-moi un moyen facile de le faire et de nuire à la performance.

Mise à jour, S'il vous plaît exécuter le script ci-dessous

 

create table [mytable] ( [id] int, [parentId] int ) GO

INSERT INTO [mytable] ([id],[parentId])VALUES(1,NULL) INSERT INTO [mytable] ([id],[parentId])VALUES(2,6) INSERT INTO [mytable] ([id],[parentId])VALUES(4,9) INSERT INTO [mytable] ([id],[parentId])VALUES(5,4) INSERT INTO [mytable] ([id],[parentId])VALUES(6,13) INSERT INTO [mytable] ([id],[parentId])VALUES(7,13) INSERT INTO [mytable] ([id],[parentId])VALUES(8,5) INSERT INTO [mytable] ([id],[parentId])VALUES(9,1) INSERT INTO [mytable] ([id],[parentId])VALUES(13,1) GO

; WITH q AS ( SELECT id, parentId, CAST(id AS VARCHAR(MAX)) + '/' AS path FROM mytable WHERE parentId IS NULL UNION ALL SELECT t.id, t.parentId, q.path + CAST(t.id AS VARCHAR(MAX)) + '/' FROM q JOIN mytable t ON t.parentId = q.id ) SELECT *, ROW_NUMBER() OVER (ORDER BY path) AS rn FROM q ORDER BY path GO

The result of this query ID ParentId Path rn 1 NULL 1/ 1 13 1 1/13/ 2 6 13 1/13/6/ 3 2 6 1/13/6/2/ 4 7 13 1/13/7/ 5 9 1 1/9/ 6 4 9 1/9/4/ 7 5 4 1/9/4/5/ 8 8 5 1/9/4/5/8/ 9

Mais je veux le résultat pour rn à partir du résultat avove premier 1 puis 1/9 then1/9/... puis 1/13/puis 1/13/... .Veuillez me donner la solution pour cela.

Je veux comme résultat

 


ID ParentId Path  rn 
1 NULL 1/  1 
13 1 1/13/  6 
6 13 1/13/6/  7 
2 6 1/13/6/2/ 8 
7 13 1/13/7/  9 
9 1 1/9/   2 
4 9 1/9/4/  3 
5 4 1/9/4/5/  4 
8 5 1/9/4/5/8/ 5 

 

 


WITH q AS 
     ( 
     SELECT id, parentId, CAST(id AS VARCHAR(MAX)) AS path 
     FROM mytable 
     WHERE parentId IS NULL 
     UNION ALL 
     SELECT t.id, t.parentId, q.path + '/' + CAST(t.id AS VARCHAR(MAX)) 
     FROM q 
     JOIN mytable t 
     ON  t.parentId = q.id 
     ) 
SELECT *, ROW_NUMBER() OVER (ORDER BY path) AS rn 
FROM q 
ORDER BY 
     path 

 

En ci-dessus encore une question. vous utilisez l'ordre par le chemin supposons, dans le cas des enregistrements comme 1/13 et 1/2, donc ordonner par est 1/13 et 1/2, mais je veux l'ordre 1/2 puis 1/13, parce que 2 est inférieur à 13.

+1

ORDER BY Ordre, id ?? – JonH

+3

Je pense qu'il y a une faute de frappe dans vos résultats attendus. Le dernier identifiant devrait-il être 6 au lieu de 4? –

Répondre

3
WITH q AS 
     (
     SELECT id, parentId, CAST(id AS VARCHAR(MAX)) + '/' AS path 
     FROM mytable 
     WHERE parentId IS NULL 
     UNION ALL 
     SELECT t.id, t.parentId, q.path + CAST(t.id AS VARCHAR(MAX)) + '/' 
     FROM q 
     JOIN mytable t 
     ON  t.parentId = q.id 
     ) 
SELECT *, ROW_NUMBER() OVER (ORDER BY path) AS rn 
FROM q 
ORDER BY 
     path 
+1

Pourriez-vous expliquer un peu, je suis confus quant à l'endroit où vous avez obtenu ce à partir de la question à portée de main. – msarchet

+0

@msarchet: il s'agit d'une hiérarchie présentée sous forme de liste d'adjacences. Le @op veut trouver la position de chaque entrée dans l'ordre des arbres. – Quassnoi

+0

Merci, ça marche vraiment. – Paresh

0

Je ne peux pas dire exactement ce que votre base de données ressemble, mais quelque chose comme ça devrait fonctionner

Select id, [Order] From Table1 Order By Order, id 
0
select id, parentid as order from table 
order by coalesce(parentid, 9999), id 
Questions connexes