2012-07-08 13 views
5

Tengo una tabla donde los productos se categorizan según una relación jerárquica, como una estructura de árbol. Tengo que seleccionar una categoría y todas las subcategorías en cualquier nivel. Ver la imagen siguiente:SQL para la relación jerárquica

enter image description here

por ejemplo, quiero una sentencia SQL que cuando me consulta pasando el id = 11, que me devuelve (19,20,21,22,23,24,25,26)

Respuesta

1
SELECT * FROM `Products` 
WHERE parentId IN (
    SELECT id FROM `Products` 
    WHERE parentId = 11) 

NOTA: Esto no funcionará si tu jerarquía es más profunda que 2 niveles.

9

Hay varias maneras diferentes de almacenar datos jerárquicos en MySQL. Consulte el número presentation de Bill Karwin que muestra cuatro opciones.

  • lista de adyacencia
  • Ruta Enumeración
  • anidada Establece
  • Cierre Tabla

Está utilizando la lista de modelos adyacencia para almacenar datos jerárquica, pero lamentablemente esta es la más duro modelo que puede elegir para consultar subárboles.

nested sets query subtree

Las opciones son:

  • cambio a un modelo diferente.
  • Restringir las consultas a n niveles de profundidad.
  • Utilice un procedimiento almacenado para consultar recursivamente. Para obtener más información al respecto, consulte la serie de artículos de Quassnoi: Hierarchical queries in MySQL.
1

Podría cambiar un poco su estructura de datos para incluir una columna de linaje calculada. Hay un great article que muestra el concepto genérico (ignore el tipo de base de datos).

Básicamente su columna de linaje computarizada debe contener la lista de los padres en ella, por ejemplo,

artículo 26 contendría \11\

Si tuviera un subelemento que podría tener

\11\subitem\

Entonces simplemente puede hacer un control similar en su tabla de linage, es mucho más rápido que una búsqueda iterativa, y podría crearlo usando un programa almacenado o desencadenadores.

Node ParentNode EmployeeID Depth Lineage 
100  NULL   1001   0 /
101  100   1002   1 /100/ 
102  101   1003   2 /100/101/ 
103  102   1004   3 /100/101/102/ 
104  102   1005   3 /100/101/102/ 
105  102   1006   3 /100/101/102/ 
0

Esta es desordenado, y que tendrá que hacer uniones n, donde n es la profundidad de la jerarquía es, pero debería funcionar:

SELECT * FROM `Products` WHERE parentId IN (
    SELECT id FROM `Products` WHERE parentId = 11) 
UNION 
SELECT * FROM `Products` WHERE parentId IN (
    SELECT id FROM `Products` WHERE parentId IN (
     SELECT id FROM `Products` WHERE parentId = 11)) 
UNION 
SELECT * FROM `Products` WHERE parentId IN (
    SELECT id FROM `Products` WHERE parentId IN (
     SELECT id FROM `Products` WHERE parentId IN (
      SELECT id FROM `Products` WHERE parentId = 11))) 
Cuestiones relacionadas