2010-03-14 79 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變量。