2013-08-06 54 views
5

Tôi mới trong mysql. Đây là bàn của tôi:mysql đệ quy (cây) cha mẹ con loại

loại bảng:

id | name  | prent 
---------------------------- 
1 | os   | null 
2 | linux  | 1 
3 | ubuntu  | 2 
4 | xubuntu  | 3 
5 | lubuntu  | 3 
6 | zubuntu  | 3 
7 | zubuntu 2 | 6 
8 | suse  | 2 
9 | fedora  | 2 
10 | windowse | 1 
11 | windowse xp | 10 
12 | windowse 7 | 10 
13 | windowse 8 | 10 
14 | food  | null 
15 | dance  | null 

Mỗi thể loại có cha mẹ và tôi muốn chuẩn bị cho họ để hiển thị trong một trình đơn thả xuống.

Đây là những gì tôi muốn nhận được:

id | name   | depth 
---------------------------- 
1 | os   | 0 
2 | -linux  | 1 
3 | --ubuntu  | 2 
4 | ---xubuntu | 3 
5 | ---lubuntu | 3 
6 | ---zubuntu | 3 
7 | ----zubuntu 2 | 4 
8 | --suse  | 2 
9 | --fedora  | 2 
10 | -windows  | 1 
11 | --windows xp | 2 
12 | --windows 7 | 2 
13 | --windows 8 | 2 
14 | food   | 0 
15 | dance   | 0 

Ở đây, loại không theo thứ tự và mã của tôi phải cung cấp để cho trẻ em loại xa cha mẹ. Thụt lề trước tên được cung cấp dựa trên độ sâu của cha mẹ của mỗi thể loại. Không có giới hạn về số lượng trẻ em của mỗi danh mục nhưng tổng số danh mục sẽ không vượt quá 100.

Có truy vấn nào cho kết quả như vậy không? Tôi thích một truy vấn có thể chạy dưới dạng active record trong một khung công tác PHP.

+1

không. mysql không hỗ trợ truy vấn đệ quy. bạn sẽ phải làm một vòng lặp lặp lại trong mã của bạn để làm việc theo cách của bạn xuống cây. –

+0

Bạn có nhìn ở đây không? http://stackoverflow.com/questions/8633497/mysql-how-to-query-parent-child?rq=1 –

+0

@EdManet, làm thế nào về số lượng độ sâu hơn một và hai? – monjevin

Trả lời

9

Điều này Thread đã dẫn tôi. Nhờ @RolandoMySQLDBA

DELIMITER $$ 
DROP FUNCTION IF EXISTS `GetAncestry` $$ 
CREATE FUNCTION `GetAncestry` (GivenID INT) RETURNS VARCHAR(1024) 
DETERMINISTIC 
BEGIN 
    DECLARE rv VARCHAR(1024); 
    DECLARE cm CHAR(1); 
    DECLARE ch INT; 

    SET rv = ''; 
    SET cm = ''; 
    SET ch = GivenID; 
    WHILE ch > 0 DO 
     SELECT IFNULL(`prent`,-1) INTO ch FROM 
     (SELECT `prent` FROM Table1 WHERE id = ch) A; 
     IF ch > 0 THEN 
      SET rv = CONCAT(rv,cm,ch); 
      SET cm = ','; 
     END IF; 
    END WHILE; 
    RETURN rv; 

END $$ 
DELIMITER ; 

Một làm việc fiddle đây.

SELECT id,GetAncestry(id) as parents from Table1 where id = 7; 

ID PARENTS 
7 6,3,2,1 
+0

cảm ơn, tôi có thể biết 'A' có nghĩa là gì ở đây không? '(SELECT 'prent' TỪ Table1 WHERE id = ch) A;' – monjevin

+0

'A' chỉ là tên bí danh cho tập hợp kết quả này: (SELECT' prent' FROM Table1 WHERE id = ch) –

+0

Tôi nhận ra hàm này mát đến mức nào Tuy nhiên, bạn có thể giải thích cách bạn sẽ sử dụng dữ liệu tổ tiên để thêm nó vào danh sách phân cấp (phần cuối của nó và bộ não của tôi không kích hoạt) – Hightower