本文介紹了MySQL-遞歸列出表中所有項的所有父項和祖先項的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
我有一個具有父/子層次結構的表,它支持多個(理論上是無限的)嵌套級別:
|------|-------------------|-------------|
| id | title | parent_id |
|------|-------------------|-------------|
| 1 | Dashboard | 0 |
| 2 | Content | 0 |
| 3 | Modules | 0 |
| 17 | User Modules | 3 |
| 31 | Categories | 17 |
| ... | | |
|------|-------------------|-------------|
我正在嘗試構建一個查詢,該查詢生成每個項目的父項的串聯(lián)列表,直到樹中最高的父項:
|------|----------------------|
| id | concatenatedParents |
|------|----------------------|
| 1 | 0 |
| 2 | 0 |
| 3 | 0 |
| 17 | 3,0 |
| 31 | 17,3,0 |
| ... | |
|------|----------------------|
根據(jù)這里的許多其他答案,我構造了以下MySQL查詢:
SELECT parentsTable._id, GROUP_CONCAT(parentsTable.parent_id SEPARATOR ',') as concatenatedParents FROM (
SELECT
@r AS _id,
(SELECT @r := parent_id FROM menu WHERE id = _id) AS parent_id,
@l := @l + 1 AS lvl
FROM
(SELECT @r := 31, @l := 0) vars,
menu m
WHERE @r <> 0
) as parentsTable
請在此處查看小提琴:http://sqlfiddle.com/#!9/48d276f/902/0
但是該查詢只適用于一個給定子ID(在本例中為31)。我未能成功展開整個表的此查詢,是否有方法重置表中每隔一行的計數(shù)器變量?
我看到許多答案建議使用固定數(shù)量的聯(lián)接,但接受可變數(shù)量級別的解決方案會更可取。
在MySQL8中,這要歸功于遞歸查詢(謝謝@gmb),但由于我們?nèi)栽贛ySQL5.7上運行,我很感興趣是否也有針對舊版本的解決方案。
推薦答案
如果您運行的是MySQL8.0,則最好使用遞歸查詢來解決此問題:
with recursive cte as (
select id, parent_id, 1 lvl from mytable
union all
select c.id, t.parent_id, lvl + 1
from cte c
inner join mytable t on t.id = c.parent_id
)
select id, group_concat(parent_id order by lvl) all_parents
from cte
group by id
Demo on DB Fiddle:
id | all_parents -: | :---------- 1 | 0 2 | 0 3 | 0 17 | 3,0 31 | 17,3,0
這篇關于MySQL-遞歸列出表中所有項的所有父項和祖先項的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,