2016-05-20 72 views
-1
ItemId  Name   parentId 
1   A    null 
2   b    null 
3   c     1 
4   d     2 
5   e     3   
6   f     4 
7   g     2 

您好我需要帮助创建sql查询。我有一个包含3列itemid,名称,parentitemid的表。我需要一个SQL查询结果父亲的孩子relation.if parentitemid id null那么它意味着根.please帮助需要帮助形成sql查询

我需要像这样的数据。

<1><3><5></5> </3></1> 
+0

1一个NULL,2 B为空,3 C 1,4 2 d,5] E 3,6- F 4,7个G 2行中的数据 –

+1

你已经尝试过了什么?你究竟在干什么? –

+0

我不知道如何创建父子关系的递归查询,如果你知道这个答案,请回复 –

回答

1

例如,你可以使用:

WITH HierarchicalTable 
AS 
(
    SELECT Id, ParentId, Name, 0 as [Level] 
     FROM YourTable 
     WHERE ParentId IS NULL 
    UNION ALL 
    SELECT YourTable.Id, YourTable.ParentId, YourTable.Name, [Level] + 1 
     FROM YourTable 
     JOIN HierarchicalTable ON HierarchicalTable.Id = YourTable.ParentId 
) 
SELECT [Level], Name FROM HierarchicalTable 
+1

我需要XML像

0

这是过于复杂的解决方案,但它会为你的问题的工作:

DECLARE @temp TABLE (ItemId int, Name char(1), parentId int,l int) 
DECLARE @xml TABLE (s nvarchar(max), e nvarchar(max), parentId int, itemid int) 
DECLARE @l int 
;WITH cte AS (
SELECT * 
FROM (VALUES 
(1, 'a', NULL),(2, 'b', NULL),(3, 'c', 1),(4, 'd', 2),(5, 'e', 3),(6, 'f', 4),(7, 'g', 2) 
) as t(ItemId, Name, parentId) 
--Here we create recursive cte to obtain levels of nesting 
), res AS (
    SELECT *, 
      1 [Level] 
    FROM cte c 
    where parentId IS null 
    UNION ALL 
    SELECT c.*, 
      [Level]+1 
    FROM res r 
    INNER JOIN cte c 
    ON c.parentId = r.ItemId 
) 
--put results into temp table 
INSERT INTO @temp 
SELECT * 
FROM res 
--obtain max level 
SELECT @l = MAX(l) 
FROM @temp 
--from max level to 1 begin 
WHILE @l > 0 
BEGIN 
    --if there is nodes with same parentid - concatinating them 
    UPDATE x 
    SET x.e = x.e + v.s + v.e 
    FROM @xml x 
    INNER JOIN @xml v 
     ON v.parentId = x.parentId and v.e !=x.e; 

    --here we merge table with results 
    -- first run <e></e> 
    -- next run <c><e></e></c> 
    -- next run <a><c><e></e></c></a> 
    MERGE @xml AS target 
    USING (
     SELECT '<'+ Name +'>' as s,'</'+ Name + '>' as e, parentId, ItemId 
     FROM @temp 
     WHERE l = @l 
     ) as source 
    ON target.parentid = source.itemid 
    WHEN NOT MATCHED THEN INSERT VALUES (source.s, source.e, source.parentId, source.ItemId) 
    WHEN MATCHED THEN 
     UPDATE 
      SET target.s = source.s + target.s, 
       target.e = target.e + source.e, 
       target.parentid = source.parentid, 
       target.itemid = source.itemid; 
    --next level down 
    SET @l = @l - 1 

END 

SELECT x --CAST(x as xml) 
FROM (
    SELECT s+e as x, 
      DENSE_RANK() OVER (PARTITION BY itemid ORDER BY s ASC) as rn 
      --need that column to obtain first one of every string for itemid 
    FROM @xml 
    ) as c 
WHERE c.rn = 1 
--FOR XML PATH ('') 

输出将是:

x 
<a><c><e></e></c></a> 
<b><d><f></f></d><g></g></b> 

如果您删除--邻近​​和在最后一次查询改变这种SELECT x --CAST(x as xml)SELECT CAST(x as xml)你会得到这样的:

<a> 
    <c> 
    <e /> 
    </c> 
</a> 
<b> 
    <d> 
    <f /> 
    </d> 
    <g /> 
</b> 
+0

感谢gofr非常有帮助的,但还需要的itemid和parentId的与节点 –

+0

在你的问题 - '<1><3><5>'在评论到现在回答'' - 别的东西。你究竟需要什么? – gofr1