0

好的,只是为了描绘我正在努力实现的目标。

我有一个 XML 文件:

<root>
    <item id="test1" level="1" />
    <item id="test2" level="1">
        <item id="test3" level="2" />
        <item id="test4" level="2" >
            <item id="test5" level="3">
                <item id="test6" level="4" />
            </item>
        </item>
        <item id="test7" level=2" />
    </item>
</root>

我很好地阅读了 XML,并将数据存储到 SQL 表中,如下所示:

让我们称之为 tableA

ID     | ParentID  | level
---------------------------
test1      NULL         1
test2      NULL         1
test3      test2        2
test4      test2        2
test5      test4        3
test6      test5        4
test7      test2        2

现在表 B 看起来像这样:

    GUID                                |  ID
    -----------------------------------------------
   c567207d-5317-4d0e-b24d-5ae3f7fa5691    test1
   4567207d-4317-4d6e-b25d-7ae3f7fa5691    test3
   a7b94a42-fb00-4011-bd5a-4b48e6e578c5    test1
   fa7989d7-1708-4a90-9bf6-c91f6cef6952    test2
   8a7989d7-5608-5690-9bf6-591f6ce56852    test7
   gta7b94a42-fb00-4011-bd5a-4b48e6e578    test6

我想编写一个 select 语句,它会使用上面的 tableA 和 TableB 给我这样的结果:

编辑:基本上认为它是一个文件路径,我想找到ID的路径,

所以基本上对于ID:test6

路径是 test2 -> test4 -> test5 -> test6

    GUID                                |  ID  |   ID_Level_1  | ID_Level_2 | ID_Level_3 | ID_Level_4    
    ---------------------------------------------------------------------------------------------------------
   c567207d-5317-4d0e-b24d-5ae3f7fa5691    test1       test1
   4567207d-4317-4d6e-b25d-7ae3f7fa5691    test3       test2     test3  
   a7b94a42-fb00-4011-bd5a-4b48e6e578c5    test1       test1     
   fa7989d7-1708-4a90-9bf6-c91f6cef6952    test2       test2
   8a7989d7-5608-5690-9bf6-591f6ce56852    test7       test2     test7
   gta7b94a42-fb00-4011-bd5a-4b48e6e578    test6       test2     test4           test5          test6

我如何实现这个结果,使用表 A 和表 B 获得上述结果所需的 SQL CALL 是什么?

4

2 回答 2

1

http://sqlfiddle.com/#!6/d41d8/8850

诀窍是使用Recursive CTE。只需剪切并粘贴以下代码,它将创建 2 个临时表,它不会删除它们。并 tweek 递归 cte 和 select 语句来获得你想要的。让我知道这是否不是您需要的。

CREATE TABLE #tempA (ID VARCHAR(20) ,PARENTID VARCHAR(20),[LEVEL] INT)

INSERT INTO #TEMPa
VALUES( 'TEST1',NULL,1)

INSERT INTO #TEMPa
VALUES( 'TEST2',NULL,1)

INSERT INTO #TEMPa
VALUES ('TEST3','TEST2',2)

INSERT INTO #TEMPa
VALUES( 'TEST4','TEST2',2)

INSERT INTO #TEMPa
VALUES ('TEST5','TEST4',3)

INSERT INTO #TEMPa
VALUES ('TEST6','TEST5',4)

INSERT INTO #TEMPa
VALUES ('TEST7','TEST2',2)

create table #tableb(guid varchar(50), id varchar(50));
insert into #tableb values ('c567207d-5317-4d0e-b24d-5ae3f7fa5691',    'test1');
insert into #tableb values ('4567207d-4317-4d6e-b25d-7ae3f7fa5691',    'test3');
insert into #tableb values ('a7b94a42-fb00-4011-bd5a-4b48e6e578c5',    'test1');
insert into #tableb values ('fa7989d7-1708-4a90-9bf6-c91f6cef6952',    'test2');
insert into #tableb values ('8a7989d7-5608-5690-9bf6-591f6ce56852',    'test7');
insert into #tableb values ('gta7b94a42-fb00-4011-bd5a-4b48e6e578',   'test6');

;WITH coolRecursionCTE as
(
SELECT a.id,a.parentid,a.id as TargetElement, 1 AS level,convert(varchar(max),a.parentid) as [path]
FROM #tempA AS a
UNION ALL
SELECT a.ID,a.parentid,c.TargetElement,c.Level+1,convert(varchar(max),a.parentid) +'->' + c.[path]   as [path]
FROM #tempA AS a 
INNER JOIN  coolRecursionCTE AS c ON c.parentid = a.id
where a.parentid is not null
)



SELECT [targetelement], [path] + '->'+[targetelement] FROM coolRecursionCTE AS c
INNER JOIN
(
select targetElement as t , max([level]) as maxLevel from coolRecursionCTE
group by TargetElement) AS E on c.TargetElement = e.t and c.[level] = e.maxLevel 
于 2013-10-08T14:45:04.013 回答
-1

在不调整存储过程示例的情况下,它可能会为您提供一个很好的起点来完成您想要做的事情。 这是我在另一个问题上提供的原始答案。

它处理一种循环方法,即获取递归分层查询并为所有尚未处理的记录填充结果表。您必须对其进行调整,并且我建议您在需要更深入的每个级别上,为您要运行它的下一列添加一个“alter table add”。您甚至可能需要进入动态 SQL,因为您的列名会不断出现。

于 2013-10-08T13:53:11.183 回答