2010-02-04 7 views
20

Digamos que usted tiene la siguiente tabla:la obtención de datos de las tablas de jerarquía de autorreferencia

items(item_id, item_parent) 

... y es una tabla de referencia a sí misma - item_parent se refiere a item_id.

Qué consulta SQL usaría para SELECCIONAR todos los elementos de la tabla junto con su profundidad, donde la profundidad de un elemento es la suma de todos los padres y abuelos de ese artículo.

Si el siguiente es el contenido de la tabla:

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

... la consulta debe recuperar el siguiente conjunto de objetos:

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

P.S. Estoy buscando un enfoque compatible con MySQL.

+2

Buscar "Recursive CTE". – RBarryYoung

+2

¿Qué base de datos y versión? Las consultas recursivas son específicas del proveedor, si se admiten. – RedFilter

+2

@RBarryYoung: Eso supone que está usando MS SQL Server. –

Respuesta

21

Si la base de datos es SQL 2005/2008 entonces ...

La forma más sencilla de conseguir esto es usar un CTE (expresión de tabla común) que está diseñado para recursivo.

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 salida es la siguiente:

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

Desde que puede darle formato como desee.

+0

¡Gracias por la sugerencia! Me encantaría ver un enfoque compatible con MySQL. –

+0

Emanuil: es su responsabilidad informar a la gente sobre los requisitos de implementación (como MySQL) * * antes de que intenten responder su pregunta. – RBarryYoung

3

Oracle tiene una sintaxis muy conveniente para recuperar datos jerárquicos como esto:

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) 

Esto comienza con los nodos raíz de sus árboles como aquellos elementos cuyo item_parent no existe en la tabla como item_id, y selecciona todos los elementos secundarios de esos nodos, junto con su profundidad en el árbol.

+0

No sabía que Oracle tenía esto. Esto es bueno saberlo. ¿No sería más eficiente si los padres tuvieran un valor nulo en la columna item_parent para que podamos evitar el "no en" y una selección adicional – jett

4

Hay un buen artículo de tecnología en el sitio web de mysql sobre datos jerárquicos en MySql: Managing Hierarchical Data in MySQL - puede encontrar algunas soluciones detalladas con pro y contras allí.

Especialmente la parte sobre "El conjunto de modelos anidados" y "Encontrar la profundidad de los nodos" debería ser de su interés.

0

Necesito encontrar una solución para la misma tarea, encontré algunos artículos, pero todavía no elegí qué camino tomar ...

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

Puede ser estos enlaces podrían ayudarle. Si encuentra una buena solución, por favor publíquela aquí. No tengo permiso para publicar más de un enlace. Añadiré algunos a los siguientes mensajes

+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- storage-of-hierarchical-data-in-a-relational-database / – user296355

Cuestiones relacionadas