相關討論連接:
ASP?id=1477009">http://expert.csdn.Net/Expert/TopicVIEw1.ASP?id=1477009
原題:
表:
Tree (ID [Integer],ParentID [Integer],Remark [varchar])
INSERT INTO Tree (ID,ParentID)
SELECT 1,0
UNION ALL
SELECT 2,1
UNION ALL
SELECT 3,1
UNION ALL
SELECT 4,2
UNION ALL
SELECT 5,4
UNION ALL
SELECT 6,5
UNION ALL
SELECT 7,2
T(F1,......)
INSERT INTO T (F1)
SELECT 1
UNION ALL
SELECT 5
UNION ALL
SELECT 3
UNION ALL
SELECT 4
UNION ALL
SELECT 1
UNION ALL
SELECT 7
UNION ALL
SELECT 6
UNION ALL
SELECT 4
UNION ALL
SELECT 5
UNION ALL
SELECT 3
UNION ALL
SELECT 4
UNION ALL
SELECT 1
UNION ALL
SELECT 7
UNION ALL
SELECT 6
UNION ALL
SELECT 4
參考 Tree 表中的父子關系,"祖先"的記錄數要包括所有"後代"的記錄數,統計 T 表中 F1 各個取值的記錄數?
ID Counts
1 15
2 10
3 2
4 8
5 4
6 2
7 2
答案及簡單分析:
/*
看了前幾個人的答案,似乎都把問題想復雜了"游標"、"臨時表"、"遞歸"。
"游標"、"臨時表" 完全可以不用!
"遞歸" 思想當然應是解決樹型結構的該想到的方法!
但是 T-SQL 的嵌套層次最多只能到 32!
icevi(按鈕工廠) 的建議是非常值得提倡的,盡管 ID,ParentID 對於僅存儲是足夠經濟的,
但是若用其提供表現形式,性能的確不會太好!
許多高效的樹型結構論壇也確實是存儲並維護各個節點的層次信息的數據,這樣
顯示起來僅需一條 SQL 即可!
下面是我的參考答案,兩個自定義函數功能幾乎一樣,都是運算出前面所提的,
應最好主動維護的"層次信息":
方法一: UDF 遞歸實現! 有 32 層嵌套限制
*/
alter FUNCTION dbo.Get32Ancestors
(@X integer)
RETURNS VARCHAR(250)
AS
BEGIN
DECLARE @ID integer
DECLARE @ReturnValue VARCHAR(250)
SELECT TOP 1 @ID = ParentID
FROM tree
WHERE [id] = @X
IF @ID <> @X
BEGIN
SELECT @ReturnValue = cast(ISNULL(dbo.Get32Ancestors(@ID),') as varchar) + '-'+ cast(@X as varchar)
END
ELSE SET @ReturnValue = @ID
RETURN @ReturnValue
END