2011-11-12 18 views
11

Estoy tratando de encontrar a todos los padres, abuelos, etc. de un campo en particular con cualquier profundidad. Por ejemplo, dada la estructura de abajo, si doy 5, los valores devueltos deben ser 1, 2, 3 y 4.Consultas jerárquicas en MySQL

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

¿Cómo voy a hacer esto?

+2

Tienes que cambiar el esquema para esto. Lea la presentación [@BillKarwin] (http://stackoverflow.com/users/20860/bill-karwin) titulada [Modelos para datos jerárquicos con SQL y PHP] (http://www.slideshare.net/billkarwin/models) -for-hierarchical-data), en los diferentes modelos y cómo implementarlos. – Shef

+0

@Shef: ¿Qué cambios debo hacer en el esquema y cómo escribo la consulta? –

+0

@BillKarwin: En tu ppt, has mencionado que la lógica anterior no se puede hacer usando mysql. ¿Es así? –

Respuesta

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 ... ¿puede ser peligroso si lo usa demasiado, como en un gran sitio web? – Wiliam

+2

@Wiliam: no es seguro para la actualización porque 'MySQL' no define claramente el comportamiento de la variable de sesión. Sin embargo, es la única forma de lidiar con listas de adyacencia de manera oportuna en consultas. – Quassnoi

+0

Solo como referencia (ya que "peligroso" puede significar algo) ¿alguien puede explicar qué pasa con esto lo hace peligroso? ¿Y qué lo haría ser/no ser peligroso? – Mike

-7

La siguiente respuesta no es solo MYSQL, sino que usa PHP. Esta respuesta puede ser útil para todos aquellos que terminan en esta página durante su búsqueda (como hice yo) pero no están limitados a usar MYSQL solamente.

Si usted tiene una base de datos con una estructura anidada de profundidad desconocida, se puede imprimir el contenido usando un bucle recursivo:

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

Esta función también se puede escribir en cualquier otro idioma como el Javascript.