Sql-Server
微軟SQL。帶條件的樹結構獲取
我需要製作一個樹形結構
表:
create table Dirs ( Id uniqueidentifier primary key not null default (newid()), Name nvarchar(30) not null, CreatedDate datetime not null default getdate(), ModifiedDate datetime not null default getdate(), IsCollapsed bit default dbo.randbit(newid()), ParentId uniqueidentifier default null )
我想從特定節點獲取所有子節點(例如通過 id),但過濾掉關閉目錄的子節點,將它們本身保留在輸出中?
例如給定結構
root - Dir1 (v) -Dir2 (v) -Dir3(x) -Dir4(v) -Dir5(v)
其中
x
- 表示目錄已折疊,v
- 表示目錄已展開。預期輸出為:
Dir1 Dir2 Dir3
我寫了這樣的查詢:
create procedure GetNodes @parentId uniqueidentifier = null as begin with dirsrec as ( select * from Dirs where Id = @parentId union all ( select d.Id, d.Name, d.CreatedDate, d.ModifiedDate, d.IsCollapsed, j.id as ParentId from Dirs d join dirsrec as j on d.ParentId = j.Id where d.IsCollapsed = 'false' ) ), dirsec2 as ( select * from Dirs where Id = @parentId union all ( select d.Id, d.Name, d.CreatedDate, d.ModifiedDate, d.IsCollapsed, j.id as ParentId from Dirs d join dirsrec as j on d.ParentId = j.Id where d.IsCollapsed = 'true' ) ) select * from dirsrec union select * from dirsec2 end
它使用2個遞歸。第一個是從給定的節點中獲取所有打開的節點,第二個是獲取所有關閉的節點,然後輸出得到區分
它可以工作,但我不喜歡使用幾乎相同的程式碼的 2 個單獨的查詢。我想它可能會做得更好
我試圖產生副作用(將
union all(
子查詢中的折疊節點插入臨時表,然後將其與最終結果合併,但看起來 sql 不允許我們在子查詢中創建一些邏輯)
WITH cte AS ( SELECT * FROM tree WHERE id = @starting_node UNION ALL SELECT tree.* FROM tree, cte WHERE tree.parent_id = cte.id AND cte.IsCollapsed = 'expanded' -- if collapsed then stop )