SQL SERVER树状结构排序
1
1.1
1.2
2
2.1
2.1.1
2.1.2
2.2
2.2.1
假如我們查詢到樹狀結構數據,并要求對其排序,排序效果如上圖。實現的思路如下:對每一層的節點按照排序字段排序,同一層節點按照排序順序獲取一個自增的rowNumberId(這里只需要調用ROW_NUMBER()函數),?這樣我們就可以單獨的對同一層的樹節點排序了,但是對不同層節點排序,結果將會如下:
1
1
1
2
2
2
3
3
不同層的同一序號的節點將會并列,這顯然不是我們要的效果。很明顯,數值字段并不能體現樹狀層級結構, 一般的我們用上面圖一的層級序號(1.1、1.2、1.1.1等等)來體現層級結構, 由此容易得出可以利用字符串來描述樹狀結構, 例如圖一序號是用實心點.來分割每一層, 這里我們可以用其它符號作為分隔符,甚至不用分隔符。現在我們已經知道了樹狀結構可以用字符串來表示,但是問題來了, 層級序號并不能直接用于排序,如1.1和10.1, 明顯的10.1應該排在1.1后面, 但是按照字典序排序結果恰恰相反。細心的你也許發現了1.1和10.1第一層的數字(1和10)長度不等, 那么把他們長度對齊是否會得到正確結果呢?Bingo,按照字典序'01'小于'10',但是用兩位數字表示同一層的序號,每一層只能有99個節點(序號為01-99),為了擴展每一層節點數量我們可以根據需要決定每一層的位數,5位可以表示99999個節點,一般已經夠用了。
具體的實現代碼如下
-- 遞歸查詢數據, 排序的主要思想是每一層的節點的排序字段長度對齊, 這樣就可以按照字符串的字典序來排序WITH TAB AS(SELECT ID, parentId, rowNumber = ROW_NUMBER() OVER(ORDER BY ID) FROM [tableName] WHERE parentId IS NULLUNION ALLSELECT S.ID, S.parentId, rowNumber = ROW_NUMBER() OVER(ORDER BY ID) FROM [tableName] S INNER JOIN TAB PON S.parentId = P.ID -- 再遞歸排序, RIGHT(CONCAT('00000', rowNumber), 5)表示每層最多有99999個節點(rowNumber 1-99999), ), TAB1 AS(SELECT ID, sortOrder = CONVERT(VARCHAR(50), RIGHT(CONCAT('00000', rowNumber), 5)), orderId = CONVERT(VARCHAR(60), rowNumber) FROM TAB WHERE parentId IS NULLUNION ALLSELECT S.ID, sortOrder = CONVERT(VARCHAR(50), P.sortOrder + RIGHT(CONCAT('00000', S.rowNumber), 5)), orderId = CONVERT(VARCHAR(60), CONCAT(P.orderId, '.', S.rowNumber)) FROM TAB S INNER JOIN TAB1 P ON S.parentId = P.ID)SELECT * FROM TAB1 ORDER BY sortOrder查詢結果:
| # | 00001 | 1 |
| ## | 0000100001 | 1.1 |
| ### | 00002 | 2 |
| #### | 0000200001 | 2.1 |
| ##### | 0000200002 | 2.2 |
| ###### | 0000200003 | 2.3 |
?
總結
以上是生活随笔為你收集整理的SQL SERVER树状结构排序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 详细总结流行前端框架Vue重难点概念
- 下一篇: 基于JAVA社区生活超市管理系统计算机毕