2013-08-06 13 views
5

Sono nuovo in mysql. Questo è il mio tavolo:mysql ricorsivo (albero) genitore figlio categoria

categoria tabella:

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 

Ogni categoria ha un genitore e voglio prepararli per mostrare in un menu a discesa.

Questo è quello che voglio ottenere:

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 

Qui, le categorie non sono in ordine e il mio codice deve fornire ordine per bambini categorie lontano dai loro genitori. Indentazione prima che il nome sia fornito in base alla profondità dei genitori di ciascuna categoria. Non esiste un limite per il numero di bambini di ogni categoria, tuttavia il numero totale di categorie non supererà 100.

C'è qualche domanda che fornisce tale risultato? Preferisco una query che può essere eseguita sotto forma di active record in un framework PHP.

+1

no. mysql non supporta query ricorsive. Dovrai fare un ciclo iterativo nel tuo codice per farti strada lungo l'albero. –

+0

Hai guardato qui? http://stackoverflow.com/questions/8633497/mysql-how-to-query-parent-child?rq=1 –

+0

@EdManet, che ne dici del numero di profondità più di uno e due? – monjevin

risposta

9

Questo Thread mi ha guidato. Grazie alla @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 ; 

Un lavoro fiddle qui.

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

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

grazie, posso sapere che cosa significa "A" qui? '(SELEZIONA 'prent' FROM Table1 WHERE id = ch) A;' – monjevin

+0

'A' è solo un nome alias per questo set di risultati: (SELECT' prent' FROM Table1 WHERE id = ch) –

+0

Riconosco quanto è interessante questa funzione , per favore puoi spiegare come useresti i dati di discendenza per aggiungerli a una lista gerarchica (è tardi e il mio cervello non sta sparando) – Hightower

Problemi correlati