2011-11-08 29 views
0

我有一個表,看起來像下面獲取分層分類的所有父母在MySQL

cat_id | name   | parent_id | Level 
------------------------------------------------- 
1   cat1    0    1 
2   subcat1    1    2 
3   subcat1-subcat  2    3 

我想知道什麼是最有效的方式來獲得cat_id 3,所以我的結果集將看起來像這樣

cat_id | name   | parent_id | Level 
-------------------------------------------------- 
1   cat1    0    1 
2   subcat1    1    2 
+0

MySQL沒有遞歸語法 - 請參閱此鏈接以獲取更多信息:http://www.artfulsoftware.com/mysqlbook/sampler/mysqled1ch20.html –

+0

僅僅是我還是不是「Level」列冗餘? –

+0

@Yzmir:取決於你如何分割這些數據。你可以計算它,但計算它可能相當醜陋(特別是在MySQL中)。 –

回答

1

你必須做多個查詢。一個你想要去的每個級別(或者把它寫成一個存儲過程)。

最有效的方法不是使用所謂的「鄰接列表模型」(您正在使用的),而是切換到「嵌套集合」。

谷歌搜索「嵌套集」會給你很多的信息。它需要一些時間才能習慣它,並編寫處理它的代碼。

1

我遇到了同樣的問題,但不幸的是在單個查詢中沒有辦法做到這一點。所以你必須寫一個函數或一個可以獲得所有父類別的存儲過程。 ALGO將作如下

**childs** = 3 
Loop (not done) 
Get immediate parents of **childs**, 
save(concat) them in a *return* variable 
update **childs** = immediate parents 
REPEAT 

回報將包含給定類別的所有家長(平)

1)功能:在功能的情況下,你會返回一個字符串值作爲函數不能返回更多超過1個值,所以你的結果會像「1,2」那樣。但這又不會完全填滿我們的目的,我們要利用這個結果在查詢

SELECT * FROM table_name where id IN ("1,2") ORDER BY LEVEL 

所以不是我們將回到我們的結果爲正則表達式),這是「^(1 | 2)$ 「

SELECT * FROM tbl_categories WHERE cat_id REGEXP "^(1|2)$" ORDER BY level; 

2)存儲過程:在存儲過程的情況下,我們可以動態並在執行該查詢,我們將有我們需要的結果準備語句。

有關存儲過程的更多詳細請求,請參閱以下教程。

Get all nested parents of a category – MySQL

0

這裏是存儲過程,你可以用它來獲取所有的父母在層次:


DROP PROCEDURE IF EXISTS sp_GetParentsByLevel; 
    delimiter $$

CREATE PROCEDURE `sp_GetParentsByLevel`(level_id varchar(36)) main : BEGIN DECLARE P_ID VARCHAR(36) DEFAULT NULL; DECLARE P_ID_ALL TEXT DEFAULT NULL; DECLARE COUNT INT DEFAULT 0; get_parents : LOOP -- get the parent of current level SELECT parent_id INTO P_ID FROM test1 WHERE cat_id = level_id; -- if current level is parent level then leave the loop IF P_ID = 0 THEN LEAVE get_parents; END IF; -- set current parent id as level id for next iteration SET level_id = P_ID; -- concat all the parents id IF COUNT = 0 THEN SET P_ID_ALL = P_ID; SET COUNT = COUNT+1; ELSE SET P_ID_ALL = CONCAT(P_ID_ALL,',',P_ID); END IF; END LOOP get_parents; -- if parent exists then execute the query, else return empty set IF P_ID_ALL IS NOT NULL THEN -- create query to generate result set SET @sqltext = CONCAT('SELECT cat_id, name, parent_id FROM test1 WHERE cat_id IN (',P_ID_ALL,')'); -- execute query PREPARE stmt FROM @sqltext; EXECUTE stmt; DEALLOCATE PREPARE stmt; END IF; END$$ mysql> CALL sp_GetParentsByLevel('3'); +--------+---------+-----------+ | cat_id | name | parent_id | +--------+---------+-----------+ | 1 | cat1 | 0 | | 2 | subcat1 | 1 | +--------+---------+-----------+ 2 rows in set (0.00 sec)

CALL sp_GetParentsByLevel( '3');

請替換表名。這個存儲過程可以用來獲取任意數量的父母。