2011-11-12 12 views
11

Sto cercando di trovare tutti i genitori, i nonni, ecc. Di un campo particolare con qualsiasi profondità. Ad esempio, data la struttura sottostante, se fornisco 5, i valori restituiti dovrebbero essere 1, 2, 3 e 4.Interrogazioni gerarchiche in MySQL

| a | b | 
----------- 
| 1 | 2 | 
| 2 | 3 | 
| 3 | 4 | 
| 4 | 5 | 
| 3 | 6 | 
| 4 | 7 | 

Come faccio a fare questo?

+2

È necessario modificare lo schema per questo. Leggi la presentazione [@BillKarwin] (http://stackoverflow.com/users/20860/bill-karwin) intitolata [Modelli per dati gerarchici con SQL e PHP] (http://www.slideshare.net/billkarwin/models -per-dati gerarchici), sui diversi modelli e su come implementarli. – Shef

+0

@Shef: Quali modifiche dovrei apportare nello schema e come scrivo la query. –

+0

@BillKarwin: Nel tuo ppt hai menzionato che la logica sopra non può essere eseguita usando mysql. È così? –

risposta

22
SELECT @id := 
     (
     SELECT senderid 
     FROM mytable 
     WHERE receiverid = @id 
     ) AS person 
FROM (
     SELECT @id := 5 
     ) vars 
STRAIGHT_JOIN 
     mytable 
WHERE @id IS NOT NULL 
+1

waw ... può essere pericoloso se lo usi troppo, come in un grande sito web? – Wiliam

+2

@Wiliam: non è sicuro per l'aggiornamento perché 'MySQL' non definisce chiaramente il comportamento delle variabili di sessione. Tuttavia, è l'unico modo per gestire gli elenchi di adiacenza in modo tempestivo durante l'interrogazione. – Quassnoi

+0

Solo per riferimento (dato che "pericoloso" può significare qualsiasi cosa) qualcuno può approfondire ciò che lo rende pericoloso? E cosa potrebbe causare/non essere pericoloso? – Mike

-7

La seguente risposta non è MYSQL-only, ma utilizza PHP. Questa risposta può essere utile per tutti quelli che finiscono su questa pagina durante la loro ricerca (come ho fatto io) ma non si limitano a usare solo MySQL.

Se si dispone di un database con una struttura annidata di profondità sconosciuta, è possibile stampare il contenuto utilizzando un ciclo ricorsivo:

function goDownALevel($parent){ 
    $children = $parent->getChildren(); //underlying SQL function 
    if($children != null){ 
      foreach($children as $child){ 
       //Print the child content here 
       goDownALevel($child); 
      } 
    } 
} 

Questa funzione può anche essere riscritta in qualsiasi altra lingua come Javascript.