SQL Server层次结构引用和交叉数据引用

时间:2018-04-03 19:30:06

标签: sql sql-server hierarchy

这可能是一个愚蠢的问题,但我不是DBA,并且有点坚持这个问题。我有一个应用程序,在应用的ID(IDParent)下逐步删除所有效果(asdf)。

数据表的设置如下:

Data Tables enter image description here

3rd Data Table

我想编写一个查询,在使用IDChild时,它会引用该条目IDParent以获取父ID,同时将其作为IDChild引用。例如,对于从116开始的数据输入,我想使用父ID(124)并在T1中获得321。我想使用它来获取与父ID为321的所有条目的RandoID相关联的RandoName。

现在我正在使用类似的脚本:

Select t.[NAME]
From T2 tv
Inner join T3 t on t.RandoID = tv.RandoId
Where
tv.IDChild = T1.IDChild OR tv.IDChild = T1.IDParent

但我不确定如何获得整个应用层次结构。

这会产生这样的结果:

Resulting Query

PS。我无法更改表/ db架构。但也许我可以添加一个来进行所有引用?请告诉我你的想法。

编辑对不起,我忘记了RandoID使用的另一个包含RandoID名称的愚蠢表。我想获得RandoID的名字

2 个答案:

答案 0 :(得分:0)

使用递归:

declare @t table (IDc int , Idp int)
insert into @t
values
(321,null)
,(123,321)
,(124,123)
,(116,124)

declare @t2 table (RandoID varchar(10), IDChild int)
insert into @t2
values('asdf',123)

;with cte as
(
    select anchor = IDChild
         ,ParentOrSelf = IDc
         ,RandoID 
         ,RandomName
    from @t
    cross join (select RandoID,RandoName from @t2 t2 join @t3 t3 on t2.RandoID=t3.RandoID) crossed
    where IDc=@anchor

    union all

    select t2.IDChild
         ,IDc
         , t2.RandoID,RandomName
    from @t t
        cross join (select RandoID,RandoName from @t2 t2 join @t3 t3 on t2.RandoID=t3.RandoID) t2
        join cte on cte.ParentOrSelf = t.Idp
)

select IDc
  , cte.RandoID,cte.RandomName
from @t t
    left join cte on t.IDc = cte.ParentOrSelf

结果:

IDc RandoID
321 NULL
123 asdf
124 asdf
116 asdf

答案 1 :(得分:0)

我认为循环可以帮助你。

试试这个:

CREATE TABLE #t1 (IDChild Int, IDParent Int);
CREATE TABLE #t2 (RandoID NVARCHAR(10) , IDChild Int);
CREATE TABLE #RandoName (RandoID NVARCHAR(10), RandoName VARCHAR(50));

INSERT INTO #t1 VALUES (321, NULL), (123,321),(124,123),(116,124)
INSERT INTO #t2 VALUES ('asdf', 123)
INSERT INTO #RandoName VALUES ('asdf', 'something')

SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 100)) [RowNum], a.IDChild a, a.IDParent b, b.IDChild c INTO #t3 FROM #t1 a
LEFT OUTER JOIN #t1 b ON b.IDParent = a.IDChild

DECLARE @rownum INT;
DECLARE cbcursor CURSOR for Select RowNum FROM #t3;
OPEN cbcursor;
Fetch Next from cbcursor into @rownum
WHILE @@FETCH_STATUS = 0
BEGIN
       UPDATE #t3
       SET c = (SELECT b from #t3 where RowNum = @rownum-1)
       WHERE RowNum = @rownum
Fetch Next from cbcursor into @rownum;
END;
Close cbcursor;
Deallocate cbcursor;

SELECT a,b,t2.RandoID, r.RandoName FROM #t3
LEFT OUTER JOIN #t2 t2 on t2.IDChild = #t3.c OR t2.IDChild = #t3.b OR t2.IDChild = #t3.a
LEFT OUTER JOIN #RandoName r on t2.RandoID = r.RandoID

这就是我得到的:

enter image description here

如果您的表中有任何更改,例如T2的更多记录,则应修改此脚本。