簡體   English   中英

MySql在具有重復節點的閉合表中排序層次結構數據

[英]MySql sorting hierarchical data in a closure table that has repeated nodes

我有一個表示為閉合表的層次結構,如Bill Karwin所述 我正在嘗試編寫一個查詢,該查詢將返回按深度優先遍歷排序的節點。 該答復將解決我的問題,除了在我的結構中某些節點不止一次出現是因為它們有多個父級。

我的樣本數據如下所示:

  • 1個
    • 2
    • 3
    • 4
      • 6
      • 2

如您所見,節點2作為根的子代和孫代出現兩次。 節點5作為根的孫子出現兩次(每次都有不同的父節點),然后又作為曾孫出現,因為它的父節點2重復了。

這會將數據設置為閉合表:

CREATE TABLE ancestor_descendant (
  ancestor int NOT NULL,
  descendant int NOT NULL,
  path_length int NOT NULL
);
INSERT INTO ancestor_descendant (ancestor, descendant, path_length) VALUES 
    (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0),(6,6,0),(1,2,1),(1,3,1),(1,4,1),
    (2,5,1),(3,5,1),(4,6,1),(4,2,1),(1,5,2),(1,6,2),(1,2,2),(1,5,3),(4,5,2);

或作為鄰接表:

CREATE TABLE parent_child (
  parent int NOT NULL,
  child int NOT NULL
);
INSERT INTO parent_child (parent, child) VALUES 
    (1,2),(1,3),(1,4),(2,5),(3,5),(4,2),(4,6);

我可以進行廣度優先遍歷(盡管5僅作為孫子出現一次):

SELECT CONCAT(LPAD('', path_length, '-'), ' ', descendant)
FROM ancestor_descendant
WHERE ancestor = 1
ORDER BY path_length;

1
- 2
- 3
- 4
-- 5
-- 6
-- 2
--- 5

但是我嘗試使用面包屑進行深度優先遍歷失敗(由於GROUP BY a.descendant它僅顯示重復的節點一次):

SELECT a.descendant, GROUP_CONCAT(b.ancestor ORDER BY b.path_length DESC) AS breadcrumbs
FROM ancestor_descendant a 
INNER JOIN ancestor_descendant b ON (b.descendant = a.descendant) 
WHERE a.ancestor = 1
GROUP BY a.descendant 
ORDER BY breadcrumbs;

1   1
2   1,1,4,1,4,1,2,2
5   1,1,4,1,4,1,3,2,3,2,5,5
3   1,3
4   1,4
6   1,4,6

是否可以使用閉合表表示形式輸出深度優先遍歷?

我應該使用其他表示形式嗎? 我不能使用遞歸CTE,因為我僅限於MySql(無法實現它們)。

我建議將節點id分為兩個概念。 一個是用於圖形屬性的唯一 ID(即ancestor_descendant列表)。 第二個是您在輸出中顯示的內容。

  • 1個
    • 2
    • 3
      • 50
    • 4
      • 6
      • 20
        • 51

然后創建一個映射表:

Id      Value
 1        1
 2        2
20        2
 3        3
 4        4
 5        5
50        5
51        5
 6        6

然后,您可以通過返回映射表並使用value列而不是id列來獲得所需的內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM