8
votes

Récupérer des groupes hiérarchiques ... avec une récursion infinie

J'ai une table comme celle-ci contenant des liens: xxx

pas vraiment bien rangé et infini ...

clé_a = parent key_b = enfant

nécessite une requête qui recomposera et attribue un numéro pour chaque groupe hiérarchique (parent + enfants directs + enfants indirects): xxx

parce que Nous avons

abca

-> seulement veulent montrer simplement le lien comme indiqué.

aucune idée?

Merci d'avance < / p>


7 commentaires

Mise à jour: problème avec une récursion infinie


Que signifie "récursion infinie"? Qu'il n'y a pas de limite théorique sur la hiérarchie? Ou que la hiérarchie boucle à un moment donné qu'il n'y ait littéralement aucun nœud sans enfant sur certaines branches? --Edit: ressemble à ce dernier, alors que voulez-vous arriver lorsque vous atteignez une boucle?


parce qu'un parent peut être un enfant dans certains cas


Je ne comprends pas ce qui est nb_group . Est-ce le niveau du parent? Si oui, dans la 3ème ligne ne devrait-il pas être 2?


J'aimerais identifier chaque groupe hiérarchique (parents + enfants directs + enfants indirects)


Comment savoir si la chaîne commence par A et non avec B ou c dans abcab -... ?


Bonjour, essayez ceci Stackoverflow.com/questions/7428669/... peut vous aider.


4 Réponses :


2
votes

Vous devez utiliser une requête récursive. Dans la première partie, nous sélectionnons tous les enregistrements qui sont des nœuds de haut niveau (sans parents) et utilisent Row_Number () code> Attribuez des numéros d'identification de groupe. Ensuite, dans la partie récursive, nous leur ajoutons aux enfants un par un et utilisez des numéros d'identification des groupes de parents.

with CTE as 
(

select t1.parent,t1.child,
       ROW_NUMBER() over (order by t1.parent) rn

from t t1 where 
not exists (select 1 from t where child=t1.parent)
union all
select t.parent,t.child, CTE.rn
from t  
join CTE on t.parent=CTE.Child  
)
select * from CTE
order by RN,parent


2 commentaires

Semble parfait mais je pense avoir un autre problème ... Certains groupes peuvent avoir une récursion infinie


@ Viséemaxence: vous devez vérifier l'union avec les enfants pour limiter votre récursivité. Stackoverflow.com/a/660145/128217



5
votes

Le problème est que vous ne traitez pas vraiment de hiérarchies strictes; Vous avez affaire à des graphiques dirigés, où certains graphiques ont des cycles. Notez que votre nbgroup n ° 1 n'a pas de racine canonique-- Cela pourrait être un, B, B ou C en raison de la référence cyclique de C-A.

La manière fondamentale de traiter cela est de penser en termes de techniques de graphique, pas de récursivité. En fait, une approche itérative (ne pas utiliser de CTE) est la seule solution que je puisse penser dans SQL. L'approche de base est expliqué ici .

Voici un violon SQL avec une solution qui aborde à la fois les cycles et l'étui à feuilles partagé. Remarquez qu'il utilise l'itération (avec un échecsafe pour empêcher les processus d'affichage) et les variables de table à utiliser; Je ne pense pas qu'il n'y ait aucun déplacement autour de cela. Notez également les données d'échantillon modifiées (A-G modifiées en A-H; expliquée ci-dessous).

Si vous creusez dans le SQL, vous remarquerez que j'ai changé des éléments clés de la solution donnée dans le lien. Cette solution concernait des bords non dirigés, tandis que vos bords sont dirigés (si vous avez utilisé des bords non écrits, l'ensemble de l'exemple d'échantillon est un seul composant en raison de la connexion A-G).

Cela arrive au cœur de la raison pour laquelle j'ai changé A-G sur A-H dans mes données d'échantillon. Votre spécification du problème est simple si seuls les nœuds de feuilles sont partagés; C'est la spécification que j'ai codée. Dans ce cas, A-H et G-H peuvent tous les deux être regroupés de leurs composants appropriés sans problème, car nous sommes préoccupés par l'accessibilité des parents (même cycles).

Cependant, lorsque vous avez des succursales partagées, ce n'est pas clair ce que vous voulez montrer. Considérez la liaison A-G: Compte tenu de cela, G-H pourrait exister dans l'une ou l'autre des composants (A-G-H ou F-G-H). Vous l'avez mis dans la seconde, mais cela aurait pu être dans le premier à la place, non? Cette ambiguïté est la raison pour laquelle je n'ai pas essayé de m'adresser dans cette solution.

EDIT: Pour être clair, dans ma solution ci-dessus, si des boues partagées sont rencontrées, elle traite l'ensemble de l'ensemble en tant que composant unique. Pas ce que vous avez décrit ci-dessus, mais il devra être changé après que le problème soit clarifié. Espérons que cela vous rapproche.


0 commentaires

0
votes

Problème douloureux du graphique marchant à l'aide de CTES récursifs. C'est le problème de la recherche de sous-graphiques connectés dans un graphique. Le défi avec des CTES récursives est de prévenir la récursion injustifiée - c'est-à-dire des boucles infinies dans SQL Server, qui signifie généralement les stocker dans une chaîne.

L'idée est d'obtenir une liste de toutes paires de nœuds connectés ( et un nœud est connecté avec lui-même). Ensuite, prenez le minimum de la liste des nœuds connectés et utilisez-le comme un identifiant pour le sous-graphique connecté.

L'autre idée est de marcher sur le graphique dans les deux sens à partir d'un nœud. Cela garantit que tous les nœuds possibles sont visités. Ce qui suit est requis qui accomplit ceci: xxx

le sqlfiddle est ici .


1 commentaires

Je remarque que votre solution a le même problème que le mien en termes de branches partagées. La mine respecte les nœuds de feuilles partagés (dans le cadre de deux composants distincts), mais comme le vôtre, fusionnera deux composants lorsque quelque chose de plus est partagé. Néanmoins, j'étais intéressé de voir la mise en œuvre de la CTE-- Bon travail!



-1
votes

Vous voudrez peut-être vérifier avec des expressions de table communes

Voici le lien < / p>


0 commentaires