2010-02-04 8 views
20

Angenommen, Sie haben die folgende Tabelle haben:Erste Hierarchiedaten aus sich selbst verweisende Tabellen

items(item_id, item_parent) 

... und es ist eine sich selbst verweisende Tabelle - item_parent bezieht sich auf item_id.

Welche SQL-Abfrage würden Sie alle Artikel, die in der Tabelle zusammen mit ihrem Tiefen SELECT verwenden, um, wo die Tiefe eines Elements ist die Summe aller Eltern und Großeltern dieses Elements.

Wenn das folgende ist der Inhalt der Tabelle:

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

... die Abfrage den folgenden Satz von Objekten abrufen soll:

{ "item_id": 1, "Tiefe": 0 }
{ "item_id": 2, "Tiefe": 0}
{ "item_id": 3, "Tiefe": 1}
{ "item_id": 4, "Tiefe": 1}
{“ item_id ": 5," Tiefe ": 2}

P. S. Ich suche nach einem von MySQL unterstützten Ansatz.

+2

Suche nach "Recursive CTE". – RBarryYoung

+2

Welche Datenbank und Version? Rekursive Abfragen sind herstellerspezifisch, sofern sie überhaupt unterstützt werden. – RedFilter

+2

@RBarryYoung: Das setzt voraus, dass er MS SQL Server verwendet. –

Antwort

21

Wenn die Datenbank SQL 2005/2008 dann ...

Der einfachste Weg, dies zu erhalten, ist mit einem CTE (Common Table Expression), die Rekursion ausgelegt ist.

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 

Die Ausgabe ist wie folgt:

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

Von dass Sie es formatieren können, wie Sie möchten.

+0

Danke für den Vorschlag! Ich würde gerne einen von MySQL unterstützten Ansatz sehen. –

+0

Emanuil: Es liegt in Ihrer Verantwortung, die Benutzer über die Implementierungsanforderungen (wie MySQL) * zu informieren * bevor * sie versuchen, Ihre Frage zu beantworten. – RBarryYoung

3

Oracle hat eine sehr günstige Syntax für hierarchische Daten wie folgt abrufen:

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) 
Diese

beginnt mit dem Wurzelknoten Ihrer Bäume wie jene Elemente, dessen item_parent existiert nicht in der Tabelle als item_id und wählt alle Kinder dieser Knoten, zusammen mit ihrer Tiefe im Baum.

+0

Ich wusste nicht, dass Oracle das hatte. Das ist gut zu wissen. Wäre es nicht effizienter, wenn Eltern in der Spalte item_parent einen Nullwert hätten, so dass wir das "not in" und ein extra select vermeiden können: – jett

4

Es gibt einen guten Tech-Artikel auf der MySQL-Website über hierarchische Daten in MySql: Managing Hierarchical Data in MySQL - Sie einige Detaillösungen mit Vor- und Nachteilen dort finden können.

der Teil über „The Nested Sets“ und „Suche nach der Tiefe des Knoten“ sollte für Sie besonders interessant sein.

0

Ich brauche eine Lösung für die gleiche Aufgabe zu finden, fand einige Artikel, aber immer noch nicht wählen, welchen Weg zu gehen ...

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

Auch diese Links könnten Ihnen helfen. Wenn Sie eine gute Lösung finden - bitte hier posten. Ich darf nicht mehr als 1 Link posten - ich werde einige zu den nächsten Posts hinzufügen

+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- Speicherung von hierarchischen Daten in einer relationalen Datenbank – user296355

Verwandte Themen