2013-08-06 15 views
5

Jestem nowa w mysql. To jest mój tabeli:mysql rekursywna (drzewo) nadrzędna kategoria dziecka

kategoria tabela:

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 

Każda kategoria ma rodziców i chcę, aby przygotować je do wyświetlania w menu rozwijanego.

To jest to, co chcę dostać:

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 

Tutaj kategorie nie są w porządku, a mój kod musi dostarczyć zamówienie na dzieci kategoriach daleko od swoich rodziców. Wcięcie przed nazwą jest podawane na podstawie głębokości rodziców każdej kategorii. Nie ma limitu liczby dzieci w każdej kategorii, jednak całkowita liczba kategorii nie przekroczy 100.

Czy istnieje zapytanie, które daje taki wynik? Wolę zapytanie, które może być uruchamiane w postaci kodu PHP w postaci active record.

+1

nie. mysql nie obsługuje zapytań rekursywnych. będziesz musiał wykonać iteracyjną pętlę w swoim kodzie, aby przejść przez drzewo. –

+0

Czy spojrzałeś tutaj? http://stackoverflow.com/questions/8633497/mysql-how-to-query-parent-child?rq=1 –

+0

@EdManet, a jeśli chodzi o liczbę głębokości większą niż jeden i dwa? – monjevin

Odpowiedz

9

To Thread doprowadziło mnie. Dzięki @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 ; 

Działający fiddle tutaj.

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

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

dziękuję, czy mogę wiedzieć, co znaczy "A"? '(SELECT 'prent' FROM Table1 WHERE id = ch) A;' – monjevin

+0

'A' to tylko nazwa aliasu dla tego zestawu wyników: (SELECT' prent' Z tabeli 1 WHERE id = ch) –

+0

Rozumiem, jak fajna jest ta funkcja , ale czy możesz wyjaśnić, w jaki sposób wykorzystać dane z przodków, aby dodać je do listy hierarchicznej (jej spóźnienie i mój mózg nie strzela) – Hightower