SQL 服务器层次结构引用和交叉数据引用
SQL Server hierarchy referencing and cross data referencing
这可能是一个愚蠢的问题,但我不是 DBA 并且有点被这个问题困住了。我有一个应用程序可以根据应用的 ID (IDParent
) 滴下所有效果 (asdf)。
数据 table 设置如下:
Data Tables
3rd Data Table
我想编写一个查询,当使用 IDChild
时,它将引用该条目的 IDParent
以获取父 ID,同时将其作为 IDChild 引用。例如,对于从 116 开始的数据条目,我想使用父 ID (124) 并在 T1 中获取 321。我想用它来获取与 RandoID 相关联的 RandoName,用于父 ID 为 321 的所有条目。
现在我正在使用类似这样的脚本:
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。我无法更改 tables/db 架构。但也许我可以添加一个来完成所有引用?请告诉我你的想法。
编辑 对不起,我忘记了 RandoID 使用的另一个愚蠢的 table,其中包含 RandoID 的名称。我正在尝试获取 RandoID
的名称
使用递归:
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
我认为一个循环可以帮助你。
试试这个:
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
这是我得到的:
如果您的表有任何更改,例如 T2 的更多记录,则应修改此脚本。
这可能是一个愚蠢的问题,但我不是 DBA 并且有点被这个问题困住了。我有一个应用程序可以根据应用的 ID (IDParent
) 滴下所有效果 (asdf)。
数据 table 设置如下:
Data Tables
3rd Data Table
我想编写一个查询,当使用 IDChild
时,它将引用该条目的 IDParent
以获取父 ID,同时将其作为 IDChild 引用。例如,对于从 116 开始的数据条目,我想使用父 ID (124) 并在 T1 中获取 321。我想用它来获取与 RandoID 相关联的 RandoName,用于父 ID 为 321 的所有条目。
现在我正在使用类似这样的脚本:
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。我无法更改 tables/db 架构。但也许我可以添加一个来完成所有引用?请告诉我你的想法。
编辑 对不起,我忘记了 RandoID 使用的另一个愚蠢的 table,其中包含 RandoID 的名称。我正在尝试获取 RandoID
的名称使用递归:
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
我认为一个循环可以帮助你。
试试这个:
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
这是我得到的:
如果您的表有任何更改,例如 T2 的更多记录,则应修改此脚本。