2013-08-06 20 views
5

Yeni mysql konumundayım.mysql özyinelemeli (ağaç) ebeveyn çocuk kategorisi

kategori tablosu: Bu benim masam

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 

Her kategori bir ebeveyne sahip ve bir açılır menüden göstermek için onları hazırlamak istiyorum.

Bu Almak istediğim şudur:

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 

Burada, kategoriler sırayla değildir ve benim kod uzakta ailelerinden çocukları kategoriler için sırasını sağlamak zorundadır. Adından önce girinti, her bir kategorinin ebeveynlerinin derinliğine göre sağlanır. Her kategorinin çocuk sayısı için bir sınırlama yoktur, ancak toplam kategori sayısı 100'ü aşmayacaktır.

Böyle bir sonuç veren herhangi bir sorgu var mı? Bir PHP çerçevesinde active record şeklinde çalıştırılabilecek bir sorguyu tercih ederim.

+1

no. mysql özyinelemeli sorguları desteklemez. Ağaca doğru ilerlemek için kodunuzda yinelemeli bir döngü yapmak zorunda kalacaksınız. –

+0

Burada baktınız mı? http://stackoverflow.com/questions/8633497/mysql-how-to-query-parent-child?rq=1 –

+0

@EdManet, bir ve ikiden fazla derinlik sayısına ne dersiniz? – monjevin

cevap

9

Bu Thread beni yönlendirdi. Burada @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 ; 

Bir çalışma fiddle teşekkürler.

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

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

teşekkürler, 'A'nın burada ne anlama geldiğini biliyor olabilir miyim? '(SELECT 'prent' Tablo 1 NEREDE = ch) A;' – monjevin

+0

'A' yalnızca bu sonuç kümesinin bir diğer adtır: (SELECT' prent' FROM Table1 WHERE id = ch) –

+0

Bu işlevin ne kadar soğuk olduğunu biliyorum Bununla birlikte, atalara ait verileri bir hiyerarşik listeye eklemek için nasıl kullanacağınızı açıklayabilir misiniz (geç ve beynim ateş etmiyor) – Hightower

İlgili konular