場(chǎng)景: 數(shù)據(jù)庫(kù)中的數(shù)據(jù)存在父子關(guān)系(單繼承,每一條記錄只有一個(gè)父記錄). 如果要查詢一條記錄以及他的所有子記錄,或者要查詢一條記錄以及他的所有父記錄.那么遞歸查詢就再合適不過(guò)了.可以簡(jiǎn)化復(fù)雜的SQL語(yǔ)句。 現(xiàn)在數(shù)據(jù)庫(kù)有一張dictionary表,用于存放業(yè)務(wù)相關(guān)字典項(xiàng)
字典表結(jié)構(gòu)(dictionary)
id,name,parent_id
字典表數(shù)據(jù)
id | name | parentId |
---|
1 | 字典1 | NULL | 1-1 | 字典1-1 | 1 | 1-2 | 字典1-2 | 1 | 2 | 字典2 | NULL | 2-1 | 字典2-1 | 2 |
開(kāi)始遞歸查詢
向下遞歸(從父到子)
WITH RECURSIVE dict AS (
SELECT *
FROM dictionary
WHERE id= '1'
union ALL
SELECT dictionary.*
FROM dictionary,
dict
WHERE dictionary.parent_id = dict.id
)
SELECT id AS id, name as name, parent_id as parentId
FROM dict
ORDER BY name
查詢結(jié)果
id | name | parentId |
---|
1 | 字典1 | NULL | 1-1 | 字典1-1 | 1 | 1-2 | 字典1-2 | 1 |
向上遞歸(從子到父)
WITH RECURSIVE dict AS (
SELECT *
FROM dictionary
WHERE id= '2-1'
union ALL
SELECT dictionary.*
FROM dictionary,
dict
WHERE dictionary.id = dict.parent_id
)
SELECT id AS id, name as name, parent_id as parentId
FROM dict
ORDER BY name
查詢結(jié)果
id | name | parentId |
---|
2 | 字典2 | NULL | 2-1 | 字典2-1 | 2 |
結(jié)語(yǔ)
- sql中WITH xxxx AS () 是對(duì)一個(gè)查詢子句做別名,同時(shí)數(shù)據(jù)庫(kù)會(huì)對(duì)該子句生成臨時(shí)表;
WITH RECURSIVE 則是一個(gè)遞歸的查詢子句,他會(huì)把查詢出來(lái)的結(jié)果再次代入到查詢子句中繼續(xù)查詢
?
//todo 此種方式都是查詢一棵樹(shù),如果結(jié)果list中有多棵截?cái)嗟臉?shù),需要遞歸查出來(lái)最頂層的parentId節(jié)點(diǎn)集合(就是找出 父節(jié)點(diǎn)對(duì)象不存在的就是頂層),然后循環(huán)這個(gè)集合挨個(gè)拼成這些樹(shù),并且再放進(jìn)一個(gè)tree集合中,從而形成一個(gè)多樹(shù)的json,但是此種方法有一個(gè)很大的問(wèn)題:效果上看導(dǎo)致小樹(shù)的頂層位置都從最前面開(kāi)始了,與實(shí)際不否,實(shí)際中應(yīng)該是錯(cuò)開(kāi)的幾棵樹(shù),綜述實(shí)際開(kāi)發(fā)中不會(huì)有這樣的結(jié)果list。
|