Solusi yang saya usulkan di sini menggunakan konsep materialized path. Berikut ini adalah contoh jalur terwujud menggunakan data sampel Anda. Saya harap ini membantu Anda untuk memahami konsep jalur terwujud:
+----+--------------------------+----------+------------------+
| ID | Name | ParentID | MaterializedPath |
+----+--------------------------+----------+------------------+
| 1 | Parent 1 | 0 | 1 |
| 2 | Parent 2 | 0 | 2 |
| 4 | Parent 2 Child 1 | 2 | 2.4 |
| 6 | Parent 2 Child 1 Child 1 | 4 | 2.4.6 |
| 7 | Parent 2 Child 1 Child 2 | 4 | 2.4.7 |
| 3 | Parent 1 Child 1 | 1 | 1.3 |
| 5 | Parent 1 Child 1 Child | 3 | 1.3.5 |
+----+--------------------------+----------+------------------+
Setiap simpul N
memiliki jalur yang terwujud, jalur ini memberi tahu Anda cara untuk pergi dari simpul akar ke simpul N
. Itu dapat dibangun dengan menggabungkan id simpul. Misalnya, untuk mencapai simpul 5
mulai dari simpul akarnya, Anda mengunjungi simpul 1
, simpul 3
, dan simpul 5
, jadi simpul 5
jalur terwujud adalah 1.3.5
Secara kebetulan, pesanan yang Anda cari dapat dicapai dengan memesan melalui jalur yang terwujud.
Pada contoh sebelumnya, jalur yang dimaterialisasikan adalah string gabungan yang dibangun, tetapi saya lebih suka penggabungan biner karena beberapa alasan.
Untuk membangun jalur yang terwujud, Anda memerlukan CTE rekursif berikut:
CREATE TABLE Tree
(
ID int NOT NULL CONSTRAINT PK_Tree PRIMARY KEY,
Name nvarchar(250) NOT NULL,
ParentID int NOT NULL,
)
INSERT INTO Tree(ID, Name, ParentID) VALUES
(1, 'Parent 1', 0),
(2, 'Parent 2', 0),
(3, 'Parent 1 Child 1', 1),
(4, 'Parent 2 Child 1', 2),
(5, 'Parent 1 Child 1 Child', 3),
(6, 'Parent 2 Child 1 Child 1', 4),
(7, 'Parent 2 Child 1 Child 2', 4)
GO
WITH T AS
(
SELECT
N.ID, N.Name, N.ParentID, CAST(N.ID AS varbinary(512)) AS MaterializedPath
FROM
Tree N
WHERE
N.ParentID = 0
UNION ALL
SELECT
N.ID, N.Name, N.ParentID, CAST( T.MaterializedPath + CAST(N.ID AS binary(4)) AS varbinary(512) ) AS MaterializedPath
FROM
Tree N INNER JOIN T
ON N.ParentID = T.ID
)
SELECT *
FROM T
ORDER BY T.MaterializedPath
Hasil:
+----+--------------------------+----------+----------------------------+
| ID | Name | ParentID | MaterializedPath |
+----+--------------------------+----------+----------------------------+
| 1 | Parent 1 | 0 | 0x00000001 |
| 3 | Parent 1 Child 1 | 1 | 0x0000000100000003 |
| 5 | Parent 1 Child 1 Child | 3 | 0x000000010000000300000005 |
| 2 | Parent 2 | 0 | 0x00000002 |
| 4 | Parent 2 Child 1 | 2 | 0x0000000200000004 |
| 6 | Parent 2 Child 1 Child 1 | 4 | 0x000000020000000400000006 |
| 7 | Parent 2 Child 1 Child 2 | 4 | 0x000000020000000400000007 |
+----+--------------------------+----------+----------------------------+
CTE rekursif di atas dimulai dengan node root. Menghitung jalur yang terwujud untuk simpul akar sangat mudah, ini adalah ID dari simpul itu sendiri. Pada iterasi berikutnya CTE menggabungkan node root dengan node anaknya. Jalur terwujud untuk simpul anak CN
adalah rangkaian dari jalur yang terwujud dari simpul induknya PN
dan id dari simpul CN
. Iterasi berikutnya naik satu tingkat ke bawah pada pohon sampai simpul daun tercapai.