2010-02-04 6 views
20

Disons que vous avez le tableau suivant:données Hiérarchie Obtenir des tables d'auto-référencement

items(item_id, item_parent) 

... et il est une table auto-référencement - item_parent fait référence à item_id.

Quelle requête SQL utiliseriez-vous pour SÉLECTIONNER tous les éléments de la table avec leur profondeur où la profondeur d'un élément est la somme de tous les parents et grands parents de cet élément.

Si ce qui suit est le contenu de la table:

item_id  item_parent 
----------- ----------- 
1   0   
2   0    
3   2   
4   2   
5   3   

... la requête doit récupérer l'ensemble des objets suivants:

{ "item_id": 1, "profondeur": 0 }
{ "item_id": 2, "profondeur": 0}
{ "item_id": 3, "profondeur": 1}
{ "item_id": 4, "profondeur": 1}
{ » item_id ": 5," depth ": 2}

P.S. Je suis à la recherche d'une approche supportée par MySQL.

+2

Rechercher "RCE Recursive". – RBarryYoung

+2

Quelle base de données et quelle version? Les requêtes récursives sont spécifiques au fournisseur, si elles sont prises en charge. – RedFilter

+2

@RBarryYoung: Cela suppose qu'il utilise MS SQL Server. –

Répondre

21

Si la base de données SQL est 2005/2008 puis ...

La meilleure façon d'obtenir ce utilise un CTE (expression commune de table) qui est conçu pour récursivité.

WITH myCTE (Item_id, Depth) 
AS 
(
    Select Item_ID, 0 as Depth From yourTable where Item_Parent=0 
    Union ALL 
    Select yourTable.Item_ID, Depth + 1 
    From yourTable 
    inner join myCte on yourTable.item_Parent = myCte.Item_Id 
) 

Select Item_id, Depth from myCTE 

La sortie est la suivante:

Item_Id Depth 
    1 0 
    2 0 
    3 1 
    4 1 
    5 2 

A partir de ce que vous pouvez formater comme vous le souhaitez.

+0

Merci pour la suggestion! J'aimerais voir une approche soutenue par MySQL. –

+0

Emanuil: il est de votre responsabilité d'informer les gens des exigences de mise en œuvre (comme MySQL) * avant * ils essaient de répondre à votre question. – RBarryYoung

3

Oracle a une syntaxe très pratique pour récupérer des données hiérarchiques comme ceci:

select 
    item_id, 
    item_parent, 
    level as depth 
from 
    items 
connect by 
    prior item_id = item_parent 
start with 
    item_parent not in (select item_id from items) 

Cela commence par les nœuds racine de vos arbres comme les éléments dont item_parent n'existe pas dans la table en tant que item_id, et sélectionne tous les enfants de ces nœuds, ainsi que leur profondeur dans l'arborescence.

+0

Je ne savais pas que Oracle avait cela. C'est bon à savoir. Cela ne serait-il pas plus efficace si les parents avaient une valeur nulle dans la colonne item_parent afin d'éviter le "not in" et une sélection supplémentaire? – jett

4

Il existe un bon article sur les données hiérarchiques MySql dans le site Web de MySQL: Managing Hierarchical Data in MySQL - vous pouvez trouver quelques solutions détaillées avec les avantages et les inconvénients.

En particulier la partie sur "Le modèle de jeu imbriqué" et "Trouver la profondeur des nœuds" devrait vous intéresser.

0

J'ai besoin de trouver une solution pour la même tâche, j'ai trouvé quelques articles, mais je n'ai toujours pas choisi la voie à suivre ...

http://explainextended.com/2009/07/20/hierarchical-data-in-mysql-parents-and-children-in-one-query/

Peut être ces liens peuvent vous aider. Si vous trouvez une bonne solution, veuillez l'envoyer ici. Je ne suis pas autorisé à poster plus de 1 lien - je vais ajouter quelques-uns aux prochains messages

+0

http://www.evolt.org/article/Four_ways_to_work_with_hierarchical_data/17/4047/ index.html – user296355

+0

http://blog.jupo.org/post/353496075/linear-traversal-of-adjacency-list-trees – user296355

+0

http://www.alandelevie.com/2008/07/12/recursion-less- stockage-de-données-hiérarchiques-dans-une-base de données relationnelle / – user296355

Questions connexes