Aşağıdaki sorgu SQL'ın sahip fıkra yararlanarak ve MySQL'in group_concat işlevi tarafından herhangi bir yol (veya yollar setleri) açmak için izin verecektir.
Aşağıdaki Ben kullanılan tablo tanımı ve örnek veriler:
drop table nested_set;
CREATE TABLE nested_set (
id INT,
name VARCHAR(20) NOT NULL,
lft INT NOT NULL,
rgt INT NOT NULL
);
INSERT INTO nested_set (id, name, lft, rgt) VALUES (1,'HEAD',1,28);
INSERT INTO nested_set (id, name, lft, rgt) VALUES (2,'A',2,3);
INSERT INTO nested_set (id, name, lft, rgt) VALUES (3,'B',4,17);
INSERT INTO nested_set (id, name, lft, rgt) VALUES (4,'B1',5,10);
INSERT INTO nested_set (id, name, lft, rgt) VALUES (5,'B1.1',6,7);
INSERT INTO nested_set (id, name, lft, rgt) VALUES (6,'B1.2',8,9);
INSERT INTO nested_set (id, name, lft, rgt) VALUES (7,'B2',11,16);
INSERT INTO nested_set (id, name, lft, rgt) VALUES (8,'B2.1',12,13);
INSERT INTO nested_set (id, name, lft, rgt) VALUES (9,'B2.2',14,15);
INSERT INTO nested_set (id, name, lft, rgt) VALUES (10,'C',18,25);
INSERT INTO nested_set (id, name, lft, rgt) VALUES (11,'C1',19,20);
INSERT INTO nested_set (id, name, lft, rgt) VALUES (12,'C2',21,22);
INSERT INTO nested_set (id, name, lft, rgt) VALUES (13,'C3',23,24);
INSERT INTO nested_set (id, name, lft, rgt) VALUES (14,'D',26,27);
Aşağıdaki sorgu size (KAFA hariç) tüm ağaç verir:
SELECT
node.id
, node.lft
, node.rgt
, node.name
, GROUP_CONCAT(parent.name ORDER BY parent.lft SEPARATOR "/" ) AS path
, (COUNT(parent.lft) - 1) AS depth
FROM nested_set AS node
inner join nested_set AS parent
on node.lft BETWEEN parent.lft AND parent.rgt
where parent.lft > 1
GROUP BY node.id
Örnek veri karşı çalıştırdığınızda, aşağıdaki bir çıkış ile:
+------+-----+-----+------+-----------+-------+
| id | lft | rgt | name | path | depth |
+------+-----+-----+------+-----------+-------+
| 2 | 2 | 3 | A | A | 0 |
| 3 | 4 | 17 | B | B | 0 |
| 4 | 5 | 10 | B1 | B/B1 | 1 |
| 5 | 6 | 7 | B1.1 | B/B1/B1.1 | 2 |
| 6 | 8 | 9 | B1.2 | B/B1/B1.2 | 2 |
| 7 | 11 | 16 | B2 | B/B2 | 1 |
| 8 | 12 | 13 | B2.1 | B/B2/B2.1 | 2 |
| 9 | 14 | 15 | B2.2 | B/B2/B2.2 | 2 |
| 10 | 18 | 25 | C | C | 0 |
| 11 | 19 | 20 | C1 | C/C1 | 1 |
| 12 | 21 | 22 | C2 | C/C2 | 1 |
| 13 | 23 | 24 | C3 | C/C3 | 1 |
| 14 | 26 | 27 | D | D | 0 |
+------+-----+-----+------+-----------+-------+
Yukarıdaki sorgu için aşağıdaki eklemeler size çeşitli bölümleri açmak için gereken kontrol verecektir:
having
depth = 0
or ('<PATH_TO_OPEN>' = left(path, length('<PATH_TO_OPEN>'))
and depth = length('<PATH_TO_OPEN>') - length(replace('<PATH_TO_OPEN>', '/', '')) + 1)
Olan fıkra sorgunun grubun sonuçlarına filtreleri geçerlidir. "Derinliği = 0" parçası, biz her zaman baz menü düğümleri (A, B, C, ve D) dışarı sağlamaktır. Bir sonraki bölümde düğümler açık olduğu kontrol eden bir parçasıdır. O bunu maçlar ve aynı zamanda sadece yoluna seviyesi açılır emin yaparsa görmek için ('') açmak istediğiniz bir dizi yolu ile düğümlerin yolunu karşılaştırır. '' Mantığı ile tamamı veya bölüm çoğaltılmış ve gerektiğinde birden çok yol açmak için gerekli olarak ilave edilebilir. '' Bölü çizgisi (/) bitmiyor emin olun.
Aşağıdaki istediğini çıktılarını almak için sorguları oluşturmak nasıl göstermek için bazı çıktı örnekler:
=========Open B==========
SELECT
node.id
, node.lft
, node.rgt
, node.name
, GROUP_CONCAT(parent.name ORDER BY parent.lft SEPARATOR "/" ) AS path
, (COUNT(parent.lft) - 1) AS depth
FROM nested_set AS node
inner join nested_set AS parent
on node.lft BETWEEN parent.lft AND parent.rgt
where parent.lft > 1
GROUP BY node.id
having
depth = 0
or ('B' = left(path, length('B'))
and depth = length('B') - length(replace('B', '/', '')) + 1)
+------+-----+-----+------+------+-------+
| id | lft | rgt | name | path | depth |
+------+-----+-----+------+------+-------+
| 2 | 2 | 3 | A | A | 0 |
| 3 | 4 | 17 | B | B | 0 |
| 4 | 5 | 10 | B1 | B/B1 | 1 |
| 7 | 11 | 16 | B2 | B/B2 | 1 |
| 10 | 18 | 25 | C | C | 0 |
| 14 | 26 | 27 | D | D | 0 |
+------+-----+-----+------+------+-------+
=========Open B and B/B1==========
SELECT
node.id
, node.lft
, node.rgt
, node.name
, GROUP_CONCAT(parent.name ORDER BY parent.lft SEPARATOR "/" ) AS path
, (COUNT(parent.lft) - 1) AS depth
FROM nested_set AS node
inner join nested_set AS parent
on node.lft BETWEEN parent.lft AND parent.rgt
where parent.lft > 1
GROUP BY node.id
having
depth = 0
or ('B' = left(path, length('B'))
and depth = length('B') - length(replace('B', '/', '')) + 1)
or ('B/B1' = left(path, length('B/B1'))
and depth = length('B/B1') - length(replace('B/B1', '/', '')) + 1)
+------+-----+-----+------+-----------+-------+
| id | lft | rgt | name | path | depth |
+------+-----+-----+------+-----------+-------+
| 2 | 2 | 3 | A | A | 0 |
| 3 | 4 | 17 | B | B | 0 |
| 4 | 5 | 10 | B1 | B/B1 | 1 |
| 5 | 6 | 7 | B1.1 | B/B1/B1.1 | 2 |
| 6 | 8 | 9 | B1.2 | B/B1/B1.2 | 2 |
| 7 | 11 | 16 | B2 | B/B2 | 1 |
| 10 | 18 | 25 | C | C | 0 |
| 14 | 26 | 27 | D | D | 0 |
+------+-----+-----+------+-----------+-------+
=========Open B and B/B1 and C==========
SELECT
node.id
, node.lft
, node.rgt
, node.name
, GROUP_CONCAT(parent.name ORDER BY parent.lft SEPARATOR "/" ) AS path
, (COUNT(parent.lft) - 1) AS depth
FROM nested_set AS node
inner join nested_set AS parent
on node.lft BETWEEN parent.lft AND parent.rgt
where parent.lft > 1
GROUP BY node.id
having
depth = 0
or ('B' = left(path, length('B'))
and depth = length('B') - length(replace('B', '/', '')) + 1)
or ('B/B1' = left(path, length('B/B1'))
and depth = length('B/B1') - length(replace('B/B1', '/', '')) + 1)
or ('C' = left(path, length('C'))
and depth = length('C') - length(replace('C', '/', '')) + 1)
+------+-----+-----+------+-----------+-------+
| id | lft | rgt | name | path | depth |
+------+-----+-----+------+-----------+-------+
| 2 | 2 | 3 | A | A | 0 |
| 3 | 4 | 17 | B | B | 0 |
| 4 | 5 | 10 | B1 | B/B1 | 1 |
| 5 | 6 | 7 | B1.1 | B/B1/B1.1 | 2 |
| 6 | 8 | 9 | B1.2 | B/B1/B1.2 | 2 |
| 7 | 11 | 16 | B2 | B/B2 | 1 |
| 10 | 18 | 25 | C | C | 0 |
| 11 | 19 | 20 | C1 | C/C1 | 1 |
| 12 | 21 | 22 | C2 | C/C2 | 1 |
| 13 | 23 | 24 | C3 | C/C3 | 1 |
| 14 | 26 | 27 | D | D | 0 |
+------+-----+-----+------+-----------+-------+
İşte bu kadar. sadece bu veya açmak için gereken her yolu için bölüm çoğaltarak devam.
http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/ durumda MySQL iç içe setleri ile çalışma hakkında genel bilgi gerekir bakın.
Herhangi bir sorunuz varsa bana bildirin.
HTH,
-Dipin