2010-03-14 74 views
18

所有父行我有一个简单的MySQL表这就是包含的类别列表,级别由PARENT_ID确定:获得在一个SQL查询

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 

我试图做一个面包屑。所以我有孩子的'身份证',我想让所有可用的父母(迭代连锁,直到我们达到0“家”)。可能有任何数量或子行数无限深。

目前我正在使用每个父级的SQL调用,这是凌乱的。 SQL中有一种方法可以在一个查询中完成这一切吗?

回答

43

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 

线@r := 5是当前页的页码。结果如下:

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

你先生...是一个天才! – 2012-03-14 17:05:18

+0

'+ 1' @标记你用可变查询创造奇迹:D – bonCodigo 2013-01-19 21:29:03

+0

WOW ......并且他们说不能完成! – Mike 2013-01-24 21:18:30

0

我想,有没有简单的方法来做到这一点,使用一个查询。

我会建议看看Nested Sets,这似乎符合您的需求。

1

真棒回答马克·拜尔斯!

也许有点迟到了,但如果你也想防止无限循环,当ID = PARENT_ID(即当数据被莫名其妙地损坏),您可以展开这样的答案:

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

除了上述解决方案:

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 | 

作者包括家长可以到后期的访问。

我想检查作者是否有权访问该帖子。

解决方案:

给文章作者的ID,并返回其所有的作者和作者的父母

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 =>分配值@r变量。