父子樹層次順序
我必須在 SQL Server 2008 R2 中跟踪數據。SQLFiddle
架構:
創建表 [dbo].[ICFilters]( [ICFilterID] [int] IDENTITY(1,1) 非空, [ParentID] [int] NOT NULL DEFAULT 0, [FilterDesc] [varchar](50) 非空, [Active] [tinyint] NOT NULL DEFAULT 1, 約束 [PK_ICFilters] 主鍵集群 ([ICFilterID] ASC)與 PAD_INDEX = 關閉, STATISTICS_NORECOMPUTE = 關閉, IGNORE_DUP_KEY = 關閉, ALLOW_ROW_LOCKS = 開, ALLOW_PAGE_LOCKS = ON ) 開 [主要] ) 開 [主要] 插入 [dbo].[ICFilters] (ParentID,FilterDesc,Active) 價值觀 (0,'產品類型',1), (1, 'ProdSubType_1', 1), (1, 'ProdSubType_2', 1), (1, 'ProdSubType_3', 1), (1, 'ProdSubType_4', 1), (2, 'PST_1.1', 1), (2, 'PST_1.2', 1), (2, 'PST_1.3', 1), (2, 'PST_1.4', 1), (2, 'PST_1.5', 1), (2, 'PST_1.6', 1), (2, 'PST_1.7', 0), (3, 'PST_2.1', 1), (3, 'PST_2.2', 0), (3, 'PST_2.3', 1), (3, 'PST_2.4', 1), (14, 'PST_2.2.1', 1), (14, 'PST_2.2.2', 1), (14, 'PST_2.2.3', 1), (3, 'PST_2.8', 1)
桌子:
| ICFILTERID | 家長 ID | 過濾器 | 活躍 | -------------------------------------------------- | 1 | 0 | 產品類型 | 1 | | 2 | 1 | ProdSubType_1 | 1 | | 3 | 1 | ProdSubType_2 | 1 | | 4 | 1 | ProdSubType_3 | 1 | | 5 | 1 | ProdSubType_4 | 1 | | 6 | 2 | PST_1.1 | 1 | | 7 | 2 | PST_1.2 | 1 | | 8 | 2 | PST_1.3 | 1 | | 9 | 2 | PST_1.4 | 1 | | 10 | 2 | PST_1.5 | 1 | | 11 | 2 | PST_1.6 | 1 | | 12 | 2 | PST_1.7 | 0 | | 13 | 3 | PST_2.1 | 1 | | 14 | 3 | PST_2.2 | 0 | | 15 | 3 | PST_2.3 | 1 | | 16 | 3 | PST_2.4 | 1 | | 17 | 14 | PST_2.2.1 | 1 | | 18 | 14 | PST_2.2.2 | 1 | | 19 | 14 | PST_2.2.3 | 1 | | 20 | 3 | PST_2.8 | 1 |
每行都有其父項的 ID 和根的
parentid = 0
. s 只是範例描述,FilterDesc
因此我無法嘗試解析這些描述以進行排序。問題
是否可以以樹狀方式選擇所有行?如果是這樣,怎麼做?當我說“樹狀”時,我的意思是遞歸地選擇父項,然後是其所有子項,然後是每個子項的所有子項,依此類推。深度優先樹遍歷。
我和我的朋友們已經嘗試過,但我們沒有找到有效的解決方案,但會繼續嘗試。我對 sql 相當陌生,所以也許這可以很容易地完成,我只是讓事情變得比必要的更難。
範例(所需)輸出:
| ICFILTERID | 家長 ID | 過濾器 | 活躍 | -------------------------------------------------- | 1 | 0 | 產品類型 | 1 | | 2 | 1 | ProdSubType_1 | 1 | | 6 | 2 | PST_1.1 | 1 | | 7 | 2 | PST_1.2 | 1 | | 8 | 2 | PST_1.3 | 1 | | 9 | 2 | PST_1.4 | 1 | | 10 | 2 | PST_1.5 | 1 | | 11 | 2 | PST_1.6 | 1 | | 12 | 2 | PST_1.7 | 0 | | 3 | 1 | ProdSubType_2 | 1 | | 13 | 3 | PST_2.1 | 1 | | 14 | 3 | PST_2.2 | 0 | | 17 | 14 | PST_2.2.1 | 1 | | 18 | 14 | PST_2.2.2 | 1 | | 19 | 14 | PST_2.2.3 | 1 | | 15 | 3 | PST_2.3 | 1 | | 16 | 3 | PST_2.4 | 1 | | 20 | 3 | PST_2.8 | 1 | | 4 | 1 | ProdSubType_3 | 1 | | 5 | 1 | ProdSubType_4 | 1 |
好的,足夠多的腦細胞已經死亡。
WITH cte AS ( SELECT [ICFilterID], [ParentID], [FilterDesc], [Active], CAST(0 AS varbinary(max)) AS Level FROM [dbo].[ICFilters] WHERE [ParentID] = 0 UNION ALL SELECT i.[ICFilterID], i.[ParentID], i.[FilterDesc], i.[Active], Level + CAST(i.[ICFilterID] AS varbinary(max)) AS Level FROM [dbo].[ICFilters] i INNER JOIN cte c ON c.[ICFilterID] = i.[ParentID] ) SELECT [ICFilterID], [ParentID], [FilterDesc], [Active] FROM cte ORDER BY [Level];
以上對我來說似乎無法正常工作。想像一下帶有 facebook 類型數據的 2 表設置。表 1,有 PostId + you 其他欄位。PostId 是自動遞增的,顯然在您的界面中,您將對 DESC 進行排序以使最新文章位於頂部。
現在是評論表。表2 此表CommentId 為主鍵,自動編號。在您的 gui 中,您希望將其顯示為 ASC,以便在閱讀執行緒時,它是有意義的。(最舊的(較小的數字)在頂部)表 2 中的其他重要鍵是:PostId(FK 回到文章)和 ParentId(FK 到 CommentId)如果這是文章的“根”評論,ParentId 將為 NULL。如果有人回複評論,則 parentId 將填充commentid。
希望你們能有所收穫。CTE 將如下所示:
WITH Comments AS ( SELECT CommentId , ParentId, CAST(CommentId AS VARBINARY(MAX)) AS Sortkey, 0 AS Indent FROM dbo.Comments WHERE ParentId IS NULL AND PostId = 105 UNION ALL SELECT b.CommentId , b.ParentId, c.Sortkey + CAST(b.CommentId AS varbinary(max)) AS Sortkey, c.Indent + 1 AS Indent FROM dbo.Comments b INNER JOIN Comments c ON c.CommentId = b.ParentId ) SELECT * FROM Comments ORDER BY Sortkey
樣本輸出
1 NULL 0x0000000000000001 0 5 1 0x00000000000000010000000000000001 1 6 5 0x000000000000000100000000000000010000000000000005 2 2 NULL 0x0000000000000002 0
在 F/B 文章 105 上,有兩條評論(CommentIds 1 和 2)然後有人在 Comment1 上回复(CommentId 5,ParentId 1),然後其他人對該回復發表評論,所以在 Comment5 上(CommentId 6,ParentId 6)
和中提琴,順序是正確的,在文章下,您現在可以按正確的順序顯示評論。為了縮進文章,使其形成和在 facebook 中一樣的輪廓(級別越深,它必須從左邊越多),我還有一個名為 Indent 的列。根是 0,然後在聯合中,我們有 c.Indent + 1 AS Indent 在程式碼中,你現在可以將縮進乘以假設 32px,並以漂亮的層次結構和輪廓顯示註釋。
我認為使用自動增量主鍵 CommentId 作為建構我的 SortKey 的驅動力沒有問題,因為與搞亂以 +1 為種子的數據庫管理鍵相比,搞亂日期(commentdate)會更好