簡體   English   中英

SQL Server遞歸分層查詢,不是最優的數據結構

[英]SQL Server recursive hierarchical query, less than optimal data structure

我有一個SQL Server 2008 R2數據庫的商業應用程序,其中包含一個應該為文件和文件夾結構建模的表,類似於<root>:<sublevel 1>:<sublevel 2> .. <sublevel n>:<文件>。 數據庫表包含值對(folder_item,parent),其中folder-item是文檔或文件夾,parent是指向表中另一行的鏈接。

我正在嘗試編寫一個每行返回兩個值的查詢:

  • 一個文件
  • 文檔的完整連接路徑,從頂級文件夾到文檔的直接容器,例如Root:Level1:Level2 ..:LevelN。

通常,遞歸查詢應該能夠處理這種情況,但是存在復雜性。 文件夾項目表包含每個文檔和子級別的冗余條目,將它們與文件夾結構中的每個祖先配對,而不僅僅是它們的直接父級。

而不是(文件,父母)(父母,祖父母)(祖父母,曾祖父母)......(祖先,根)

該表包含(文件,父母)(文件,祖父母)...(文件,祖先)(文件,根)(父母,祖父母)...(父母,祖先)(父母,根)...(祖父母,曾祖父母)...(祖父母,根)

等等。 我確信數據建模者有他們設計的原因,但它否定了標准遞歸分層查詢的使用。 實際上,當我嘗試時,執行超過了最大遞歸級別數。

有沒有其他人遇到過類似的問題,如果不采用超出標准SQL功能的復雜編程,是否可以解決?

非常感謝

帕特里克

如果你有:

(文件,父母)(文件,祖父母)...(文件,祖先)(文件,根)(父母,祖父母)...(父母,祖先)(父母,根)...(祖父母,曾祖父母) )...(祖父母,根)

您希望僅將遞歸限制為:

(文件,父母)(父母,祖父母)(祖父母,曾祖父母)(曾祖父母,祖父母)

對? 所以訣竅就是弄清楚在遞歸cte的下半部分放置什么條件,這樣當前行的每個相對都不會加入當前行。

所以對於document ,你想要parent 對於parent ,你想要grandparent等等。 我們如何創建此過濾器?

那么對於document什么是真正的關於parent是不是真的任何其他的祖先?

答案: documentparent有完全相同的親屬,但只有documentparent作為祖先。

因此,當您查看每個folder_item的父項時,如果存在另一行,其中父項的父項與當前項的父項之一相同,那么該folder_item不是當前folder_item的直接父項,應該過濾掉遞歸連接。

想象一下采訪:“所以你是我的祖先之一。如果我的其他祖先都沒有你作為祖先,那么你一定是我的直系父母。”

真的,不是嗎?

我沒有你的結構進行測試,但我想像在你的遞歸連接中添加這樣的東西會起作用,但它可能需要一些調整......

{for recursion -- Join second half of UNION back to main CTE}
ON bottom.Folder_Item=cte.parent  --you are my ancestor
AND NOT EXISTS(
 SELECT * FROM MyTable mt --others
 WHERE mt.folder_item<>bottom.folder_item --the other is not you
 AND mt.Folder_Item=cte.parent --the other is also my ancestor
 AND mt.Parent=bottom.folder_item --the other also has you as ancestor
)

對於這個片段bottom是我的遞歸UNION的下半部分的別名,而cte是整個CTE的別名。

通過將此過濾器置於JOIN條件中進行遞歸,我認為它應該防止遞歸樹變得瘋狂並超過遞歸限制。

如果你仍然得到遞歸限制,嘗試在遞歸CTE之前在CTE中以這種方式預過濾你的表,這樣你就可以在做遞歸之前預先消除所有非直接祖先。

我認為這應該可以工作,但如果沒有,你絕對可以用CURSOR做你需要的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM