2010-02-04 18 views
20

Diciamo che si ha la seguente tabella:ottenere i dati gerarchici da tabelle autoreferenziali

items(item_id, item_parent) 

... ed è un autoreferenziale tavolo - item_parent si riferisce a item_id.

Quale query SQL verrà utilizzata per SELEZIONARE tutti gli elementi nella tabella insieme alla loro profondità in cui la profondità di un articolo è la somma di tutti i genitori e i nonni di quell'elemento.

Se il seguente è il contenuto della tabella:

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

... la query deve recuperare la seguente serie di oggetti:

{ "item_id": 1, "profondità": 0 }
{ "item_id": 2, "profondità": 0}
{ "item_id": 3, "profondità": 1}
{ "item_id": 4, "profondità": 1}
{" item_id ": 5," profondità ": 2}

P.S. Sto cercando un approccio supportato da MySQL.

+2

Cerca "CTE ricorsivo". – RBarryYoung

+2

Quale database e versione? Le query ricorsive sono specifiche del fornitore, se supportate del tutto. – RedFilter

+2

@RBarryYoung: Questo presuppone che stia utilizzando MS SQL Server. –

risposta

21

Se il database è SQL 2005/2008 poi ...

Il modo più semplice per ottenere questo sta usando una CTE (Common Table Expression) che è progettato per recurse.

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 

L'uscita è la seguente:

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

Da che è possibile formattare come si desidera.

+0

Grazie per il suggerimento! Mi piacerebbe vedere un approccio supportato da MySQL. –

+0

Emanuil: è tua responsabilità informare la gente dei requisiti di implementazione (come MySQL) * prima * cercano di rispondere alla tua domanda. – RBarryYoung

3

Oracle ha un molto conveniente sintassi per il recupero dei dati gerarchici in questo modo:

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) 

Questo inizia con i nodi radice degli alberi come quegli elementi il ​​cui item_parent non esiste nella tabella come item_id, e seleziona tutti i figli di quei nodi, insieme con la loro profondità nell'albero.

+0

Non sapevo che Oracle avesse questo. Questo è bello sapere. Non sarebbe più efficiente se i genitori avessero un valore nullo nella colonna item_parent in modo da evitare il "non in" e selezionare in più – jett

4

C'è un buon articolo tecnico sul sito Web mysql sui dati gerarchici in MySql: Managing Hierarchical Data in MySQL - potete trovare alcune soluzioni dettagliate con pro e contro lì.

In particolare la parte relativa a "Il modello di set annidato" e "Ricerca della profondità dei nodi" dovrebbe essere di vostro interesse.

0

Ho bisogno di trovare una soluzione per lo stesso compito, ho trovato alcuni articoli, ma ancora non ho scelto quale strada da percorrere ...

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

Può essere questi collegamenti potrebbero aiutarvi. Se trovi una buona soluzione, per favore postala qui. Non sono autorizzato a postare più di 1 link - ne aggiungerò alcuni ai prossimi post

+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- stoccaggio-of-gerarchico-data-in-a-relazionale database / – user296355

Problemi correlati