2013-10-07 18 views
0

好吧,只是畫一幅我想要實現的圖片。SQL如何分組兩個單獨的表,以獲得此輸出

我有一個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語句,那會給我這樣用表A和表B從上面的結果:

編輯:基本上認爲它是一個文件路徑,我想找到路徑ID,

所以基本上對ID:TEST6

路徑將是測試2 - > 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是什麼?

+1

我明白你想要什麼的基本邏輯,但我想知道爲什麼test3作爲ID的行帶來所有其他ID? 另外,爲什麼test3和test4一起在第2級? – Gidil

+0

Levels的方式,在最終的結果中,它必須從該ID的最頂層父項開始,然後才能到達最低層 –

+0

好的,現在我明白了邏輯。這比一開始我想的要複雜得多。 – Gidil

回答

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 
+0

I認爲你的基本功能非常接近解決方案,但你可以調整一些如何讓數據顯示爲我的最終結果,我需要它們在單獨的列而不是 - >,並且我還需要從它的匹配GUID tableB也是如此,所以基本上我希望最終結果與我上面發佈的結果完全相同 –

+0

此外,還有一些與結果不一致的地方,例如test6和test5出現錯誤,層次結構不正確。 –

+0

@prakash,我更新了sql提琴手,以解決摺疊 – gh9

-1

不調整存儲過程示例,它可能會給你一個很好的啓動你想要做的事情。 Here is the original answer I provided on another question.

它處理遞歸層次查詢和爲所有尚未處理的記錄填充結果表的循環方法。您必須對其進行調整,並且我建議您在每個級別都需要更深入一些,爲您要運行的下一列添加「alter table add」。你甚至可能需要進入動態SQL,因爲你的列名將繼續出去。

+0

我不認爲動態表是必需的,因爲根據已定義的結構,最多隻能有4個級別,但如果沒有數據表示該列,我想隱藏列名稱 –

相關問題