2010-03-14 20 views
18

Tengo una sencilla tabla de MySQL eso contiene una lista de categorías, el nivel está determinado por parent_id:Conseguir todas las filas de los padres en la consulta SQL uno

id name parent_id 
--------------------------- 
1 Home  0 
2 About  1 
3 Contact  1 
4 Legal  2 
5 Privacy  4 
6 Products 1 
7 Support  1 

Estoy tratando de hacer una ruta de navegación. Así que tengo la 'id' del niño, quiero obtener todos los padres disponibles (iterando la cadena hasta que lleguemos a 0 "Inicio"). Podría haber cualquier número o filas secundarias que lleguen a una profundidad ilimitada.

Actualmente estoy usando una llamada SQL para cada padre, esto es desordenado. ¿Hay alguna forma en SQL para hacer esto todo en una consulta?

Respuesta

43

Adaptado de here:

SELECT T2.id, T2.name 
FROM (
    SELECT 
     @r AS _id, 
     (SELECT @r := parent_id FROM table1 WHERE id = _id) AS parent_id, 
     @l := @l + 1 AS lvl 
    FROM 
     (SELECT @r := 5, @l := 0) vars, 
     table1 h 
    WHERE @r <> 0) T1 
JOIN table1 T2 
ON T1._id = T2.id 
ORDER BY T1.lvl DESC 

La línea @r := 5 es el número de página de la página actual. El resultado es el siguiente:

1, 'Home' 
2, 'About' 
4, 'Legal' 
5, 'Privacy' 
+6

usted señor ... ¡¡¡es un GENIO !! –

+0

'+ 1' @Mark haces maravillas con las consultas variables: D – bonCodigo

+0

WOW ... ¡y dijeron que no se podía hacer! – Mike

0

creo, no hay manera fácil de hacer que, mediante una consulta.

Yo recomendaría echar un vistazo a Nested Sets, que parece ajustarse a sus necesidades.

1

Awesome answer by Mark Byers!

Tal vez un poco tarde a la fiesta, pero si también desea evitar un bucle infinito cuando id = parent_id (es decir, cuando los datos se han corrompido de alguna manera), se puede ampliar la respuesta de esta manera:

SELECT T2.id, T2.name 
FROM (
    SELECT 
     @r AS _id, 
     @p := @r AS previous 
     (SELECT @r := parent_id FROM table1 WHERE id = _id) AS parent_id, 
     @l := @l + 1 AS lvl 
    FROM 
     (SELECT @r := 5, @p := 0, @l := 0) vars, 
     table1 h 
    WHERE @r <> 0 AND @r <> @p) T1 
JOIN table1 T2 
ON T1._id = T2.id 
ORDER BY T1.lvl DESC 
0

Además de las soluciones anteriores:

post 
----- 
id 
title 
author 

author 
------ 
id 
parent_id 
name 


[post] 

id | title | author | 
---------------------- 
1 | abc | 3  | 


[author] 

| id | parent_id | name | 
|---------------------------| 
| 1  | 0   | u1 | 
| 2  | 1   | u2 | 
| 3  | 2   | u3 | 
| 4  | 0   | u4 | 

un autor, incluyendo los padres pueden tener un acceso al cargo.

Quiero comprobar si el autor tiene acceso a la publicación.

Solución:

dan Identificación del autor de correos y volver todos los autores y los padres del autor

SELECT T2.id, T2.username 
FROM (
    SELECT @r AS _id, 
     (SELECT @r := parent_id FROM users WHERE id = _id) AS parent_id, 
     @l := @l + 1 
    FROM 
     (SELECT @r := 2, @l := 0) vars, 
     users h  
    WHERE @r <> 0) T1 JOIN users T2 
ON T1._id = T2.id; 

@r: = 2 => valor a asignar @r variable.

Cuestiones relacionadas