2009-10-16 5 views
0

J'ai un problème Je me demandais s'il y avait une solution élégante à. C'est un vrai problème d'affaires et pas une tâche de classe!Déterminer la hiérarchie des enregistrements dans une base de données SQL

J'ai une table avec des milliers d'enregistrements, dont certains sont liés les uns aux autres.

La base de données SQL est 2005.

ID est la clé primaire. Si l'enregistrement a remplacé un enregistrement antérieur, l'ID de cet enregistrement se trouve dans la colonne REP_ID.

ID REP_ID  

E  D 
D  B 
C  B 
B  A 
A  NULL 

Ainsi, dans cet exemple, A est la ligne originale, B remplacé A, C remplacé B sans succès, D remplacé B avec succès et finalement E remplacé D.

Je voudrais pouvoir afficher tous les enregistrements de cette table dans une grille. Ensuite, je voudrais que l'utilisateur puisse faire un clic droit sur n'importe quel enregistrement dans un groupe , et que le système trouve tous les enregistrements liés et les affiche dans une sorte d'arborescence.

Maintenant, je peux évidemment forcer une solution à cela, mais je voudrais demander à la communauté s'ils peuvent voir une réponse plus élégante.

+0

Peut-être que vous devriez attendre jusqu'à ce que quelqu'un (moi dans ce cas) offre une solution SQL pour recurse la hiérarchie. – gbn

Répondre

0

Utilisez un CTE pour créer votre hiérarchie. Quelque chose comme

CREATE TABLE #test(ID CHAR(1), REP_ID CHAR(1) NULL) 

INSERT INTO #test VALUES('E','D') 
INSERT INTO #test VALUES('D','B') 
INSERT INTO #test VALUES('C','B') 
INSERT INTO #test VALUES('B','A') 
INSERT INTO #test VALUES('A',NULL) 


WITH tree( ID, 
     REP_ID, 
     Depth 
     ) 
AS 
(
    SELECT 
    ID, 
    REP_ID,   
    1 AS [Depth]     
    FROM 
    #test 
    WHERE 
    REP_ID IS NULL 

    UNION ALL 

    SELECT 
    [test].ID, 
    [test].REP_ID,   
    tree.[Depth] + 1 AS [Depth]     
    FROM 
    #test [test] 
    INNER JOIN 
    tree 
    ON 
    [test].REP_ID = tree.ID 
) 

SELECT * FROM tree 
+0

c'est superbe. Je n'ai jamais vu d'expressions CTE auparavant. Je vous remercie! – user69374

-1

Vous l'avez probablement déjà considéré mais avez-vous regardé en ajoutant simplement une ligne pour stocker le "original_id"? Cela rendrait vos requêtes rapides comparé à la construction d'un arbre de qui a hérité de qui.

Sauf cela, il suffit de google pour "SQL tree DFS". Assurez-vous d'avoir une optimisation pour votre DFS comme suit: si vous savez que la plupart des enregistrements ont seulement < = 3 révisions, vous pouvez commencer par un joint à 3 voies pour trouver A, B et C tout de suite.

+0

L'ajout d'un 'original_id' n'est pas vraiment une option. J'ai trouvé cette page en fonction de votre recommandation http://vyaskn.tripod.com/hierarchies_in_sql_server_databases.htm Il y a une tonne de liens sur il La chose intéressante sera de déterminer la hiérarchie de tout point dans la hiérarchie - que l'exemple initial commence à la racine je pense que – user69374

+0

Je suppose que ça va être un cas de (1) trouver la racine et (2) montrer la hiérarchie. Merci! – user69374

+0

Ou Google "Recursive CTE" ... – gbn

2

Il est un recursive CTE dont vous avez besoin, quelque chose comme (non testé)

;WITH myCTE AS 
(
    SELECT 
     ID 
    FROM 
     myTable 
    WHERE 
     REP_ID IS NULL 
    UNION ALL 
    SELECT 
     ID 
    FROM 
     myTable T 
     JOIN 
     myCTE C ON T.REP_ID = C.ID 
) 
SELECT 
    * 
FROM 
    myCTE 

Cependant, les liens C> B et D> B

  • Vous voulez que le C> B ou tous les deux?
  • Voulez-vous un classement?
  • etc?
Questions connexes