SQL如何对两个单独的表进行分组,以获得此输出

时间:2013-10-07 19:02:41

标签: sql sql-server-2008 pivot

好的只是为了描绘我想要实现的目标。

我有一个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>

我读得很好,并将数据存储到这样的SQL表中:

让我们调用此表

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 - &gt; test4 - &gt; test5 - &gt; 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是什么?

2 个答案:

答案 0 :(得分:1)

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

诀窍是使用Recursive CTE。只需剪切并粘贴以下代码,它将创建2个临时表,它不会丢弃它们。并调整递归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 

答案 1 :(得分:-1)

如果不调整存储过程示例,它可能会为您提供一个良好的启动,使您可以执行此操作。 Here is the original answer I provided on another question.

它处理循环方法,获取递归层次查询并为尚未处理的所有记录填充结果表。您将不得不调整它,我建议您在每个级别都需要更深入,为您将运行它的下一列添加“alter table add”。您可能甚至需要进入动态SQL,因为您的列名将继续存在。