简体   繁体   English

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

[英]SQL How to group two separate tables, to get this output

ok just to paint a picture of what i am trying to achieve. 好吧,只画一张我想要达到的目标。

I have an XML file: 我有一个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>

I read the XML fine, and store the data into a SQL table like this: 我阅读XML很好,然后将数据存储到这样的SQL表中:

Lets call this 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

Now table B looks like this: 现在表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

I want to write a select statement, that would give me a result like this using tableA and TableB from above: 我想编写一条select语句,使用上面的tableA和TableB给我这样的结果:

EDIT: Basically think of it as a file path, I want to find the path to the ID, 编辑:基本上将其视为文件路径,我想找到ID的路径,

so basically for ID: test6 所以基本上是ID:test6

path would be test2 -> test4 -> test5 -> 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

How do I achieve this result, what is the SQL CALL required to get the result above, using Table A and Table B? 我如何获得此结果,使用表A和表B获得上述结果所需的SQL CALL是什么?

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

The trick was using a Recursive CTE . 诀窍是使用递归CTE Just cut and paste the following code and it will create 2 temp tables IT WILL NOT DROP THEM. 只需剪切并粘贴以下代码,它将创建2个临时表,而不会删除它们。 And tweek the recursive cte and select statement to get what you want. 然后,递归执行cte和select语句以获取所需的内容。 Let me know if this isnt what you need. 让我知道这是否不是您所需要的。

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 

Without adjusting the stored procedure sample, it might give you a good jump-start to what you are looking to do. 在不调整存储过程示例的情况下,它可能会为您提供一个良好的起点,帮助您开始寻找要执行的操作。 Here is the original answer I provided on another question. 这是我在另一个问题上提供的原始答案。

It handles a cycling approach of getting recursive hierarchical querying and populating a result table for all records not already processed. 它处理循环方法,以获取递归层次查询并为所有尚未处理的记录填充结果表。 You would have to adjust it, and I would suggest at each level you need to go deeper, add an "alter table add " for the next column you would be running it for. 您将不得不对其进行调整,我建议您在每个级别上都需要做得更深一些,在要为其运行的下一列中添加“ alter table add”。 You might even need to get into dynamic-SQL as your column names will keep going out. 您甚至可能需要进入动态SQL,因为您的列名将不断消失。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM