查询树形的根节点
數(shù)據(jù)庫環(huán)境:SQL SERVER 2005
有一個(gè)test表,其表結(jié)構(gòu)及數(shù)據(jù)如下圖1。其中,id是主鍵,mid是當(dāng)前節(jié)點(diǎn),pid是父節(jié)點(diǎn)。
要求:查出每個(gè)節(jié)點(diǎn)的根節(jié)點(diǎn),如圖2所示。
分析:這需求實(shí)際上樹形查詢的擴(kuò)展,我們可以先找到根節(jié)點(diǎn),從根節(jié)點(diǎn)往下找到分支節(jié)點(diǎn),
再從分支節(jié)點(diǎn)往下找葉子節(jié)點(diǎn)。
1.數(shù)據(jù)準(zhǔn)備
WITH x0
AS ( SELECT 1 AS id ,
'A' AS mid ,
'B' AS pid
UNION ALL
SELECT 2 AS id ,
'B' AS mid ,
'C' AS pid
UNION ALL
SELECT 3 AS id ,
'C' AS mid ,
'N' AS pid
UNION ALL
SELECT 4 AS id ,
'D' AS mid ,
'E' AS pid
UNION ALL
SELECT 5 AS id ,
'E' AS mid ,
'G' AS pid
UNION ALL
SELECT 6 AS id ,
'G' AS mid ,
'K' AS pid
UNION ALL
SELECT 7 AS id ,
'J' AS mid ,
'H' AS pid
)
View Code
2.找到根節(jié)點(diǎn)
,/*找到?jīng)]有父節(jié)點(diǎn)的節(jié)點(diǎn),即根節(jié)點(diǎn)*/
x1
AS ( SELECT t1.* ,
t2.mid AS root_flag
FROM x0 t1
LEFT JOIN x0 t2 ON t2.mid = t1.pid
)
View Code
3.遞歸查詢
,/*從根節(jié)點(diǎn)往下遞歸*/
x2 ( id, mid, pid, rid, way )
AS ( SELECT t1.id ,
t1.mid ,
t1.pid ,
CONVERT(VARCHAR(10), t1.pid) AS rid ,
CONVERT(VARCHAR(20), t1.pid + ',' + t1.mid) AS way
FROM x1 t1
WHERE t1.root_flag IS NULL
UNION ALL
SELECT t1.id ,
t1.mid ,
t1.pid ,
CONVERT(VARCHAR(10), LEFT(t2.way,
CHARINDEX(',', t2.way) - 1)) AS rid ,
CONVERT(VARCHAR(20), t2.way + ',' + t1.mid) AS way
FROM x1 t1
INNER JOIN x2 t2 ON t2.mid = t1.pid
)
SELECT id ,
mid ,
pid ,
rid
FROM x2
ORDER BY id
View Code
綜合整個(gè)SQL,test表總共被掃描了4次才實(shí)現(xiàn)結(jié)果。期待有大神提出更好的解決方法。
總結(jié)
- 上一篇: 拉普拉斯和z变换
- 下一篇: crm 系统项目(一) 登录,注册,校验