Jer*_*emy 2 sql-server sql-server-2000 hierarchy
我有一个描述层次结构的表:
Name MemberName
A B
A C
B D
D E
F G
Run Code Online (Sandbox Code Playgroud)
MemberName引用同一个表的Name列.从这张表中,我可以轻松查询B和C是A中的成员,D是B的成员,E是D的成员,G是F的成员.
基于这种结构,很难编写一个查询,表明D和E也间接成为A的成员.D和E也间接成为B的成员等等.所以我需要做的是建立一个新的表该节目显示了所有间接成员.所以对于上面的表数据,我最终会得到一个包含以下内容的表:
Name MemberName
A B
A C
A D
A E
B D
B E
D E
F G
Run Code Online (Sandbox Code Playgroud)
我首先将所有不是其他记录(顶级)记录成员的记录放入临时表中:
CREATE TABLE #TMP
(
[Name] varchar(20),
[MemberName] varchar(20)
)
DECLARE @iRowsFound INT
INSERT INTO #TMP ([Name],[MemberName])
(SELECT * FROM [HierarchyData] WHERE [Name] NOT IN
(SELECT [MemberName] FROM [HierarchyData]))
SELECT @iRowsFound = @@ROWCOUNT
Name MemberName
A B
A C
F G
Run Code Online (Sandbox Code Playgroud)
然后我的理论是,在一个while循环中,将临时表交叉连接到heirachy表,并将来自交叉连接的适用记录插回到临时表中,并执行while循环,直到十字架中没有更多适用的记录加入以插入:
WHILE (@iRowsFound > 0)
BEGIN
INSERT INTO #TMP ([Name],[MemberName])
(
SELECT
[NewName] = ??,
[NewMember] = ??
FROM
[HierarchyData],[#TMP]
WHERE
???
)
SELECT @iRowsFound = @@ROWCOUNT
END
Run Code Online (Sandbox Code Playgroud)
我只是不确定我是否在正确的轨道上,因为我对交叉连接选择应该是什么感觉有点难过.有没有人做过这样的事情(在sql server 2000中)?
编辑:我想我可能已经得到它: - 虽然我很确定必须有一个更有效的方法来做到这一点......
WHILE (@iRowsFound > 0)
BEGIN
INSERT INTO #TMP ([Name],[MemberName])
(
SELECT
--[#TMP].[Name],
--[#TMP].[MemberName],
[HierarchyData].[Name],
[HierarchyData].[MemberName]
FROM
[#TMP]
JOIN
[HierarchyData] ON [#TMP].[MemberName] = [HierarchyData].[Name]
--WHERE
-- [#TMP].[MemberName] = [HierarchyData].[Name]
AND NOT EXISTS (SELECT * FROM [#TMP] WHERE [#TMP].[Name] = [HierarchyData].[Name] AND [#TMP].[MemberName] = [HierarchyData].[MemberName])
UNION
SELECT
[#TMP].[Name],
--[#TMP].[MemberName],
--[HierarchyData].[Name],
[HierarchyData].[MemberName]
FROM
[#TMP]
JOIN
[HierarchyData] ON [#TMP].[MemberName] = [HierarchyData].[Name]
AND NOT EXISTS (SELECT * FROM [#TMP] WHERE [#TMP].[Name] = [#TMP].[Name] AND [#TMP].[MemberName] = [HierarchyData].[MemberName])
)
SELECT @iRowsFound = @@ROWCOUNT
END
Run Code Online (Sandbox Code Playgroud)
很遗憾你不是在SQL Server 2005或更高版本上,使用递归CTE很容易,代码在这里:
WITH Members AS
(
Select Name, MemberName
FROM HierarchyData
UNION ALL
SELECT Name, Child.MemberName as [MemberName]
FROM Members
JOIN HierarchyData Child ON Members.MemberName = Child.Name
)
SELECT * FROM Members
Run Code Online (Sandbox Code Playgroud)
在2000年你可以基本上以相同的方式完成它(将最后一个选择的结果连接到原始表,直到你没有循环中最后一个集的结果),但它更难,因为你必须跟踪什么迭代你在柜台上.呸.
这有用吗,或者你想要一些sql 2000伪代码?
更好的是,升级!