本文介紹了MySQL-遞歸列出表中所有項(xiàng)的所有父項(xiàng)和祖先項(xiàng)的處理方法,對大家解決問題具有一定的參考價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!
問題描述
我有一個(gè)具有父/子層次結(jié)構(gòu)的表,它支持多個(gè)(理論上是無限的)嵌套級別:
|------|-------------------|-------------|
| id | title | parent_id |
|------|-------------------|-------------|
| 1 | Dashboard | 0 |
| 2 | Content | 0 |
| 3 | Modules | 0 |
| 17 | User Modules | 3 |
| 31 | Categories | 17 |
| ... | | |
|------|-------------------|-------------|
我正在嘗試構(gòu)建一個(gè)查詢,該查詢生成每個(gè)項(xiàng)目的父項(xiàng)的串聯(lián)列表,直到樹中最高的父項(xiàng):
|------|----------------------|
| id | concatenatedParents |
|------|----------------------|
| 1 | 0 |
| 2 | 0 |
| 3 | 0 |
| 17 | 3,0 |
| 31 | 17,3,0 |
| ... | |
|------|----------------------|
根據(jù)這里的許多其他答案,我構(gòu)造了以下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
請?jiān)诖颂幉榭葱√崆伲篽ttp://sqlfiddle.com/#!9/48d276f/902/0
但是該查詢只適用于一個(gè)給定子ID(在本例中為31)。我未能成功展開整個(gè)表的此查詢,是否有方法重置表中每隔一行的計(jì)數(shù)器變量?
我看到許多答案建議使用固定數(shù)量的聯(lián)接,但接受可變數(shù)量級別的解決方案會(huì)更可取。
在MySQL8中,這要?dú)w功于遞歸查詢(謝謝@gmb),但由于我們?nèi)栽贛ySQL5.7上運(yùn)行,我很感興趣是否也有針對舊版本的解決方案。
推薦答案
如果您運(yùn)行的是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
這篇關(guān)于MySQL-遞歸列出表中所有項(xiàng)的所有父項(xiàng)和祖先項(xiàng)的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,