2016-01-05 36 views
2

李正在试图压平/从表一中父子层次相结合的行。我试图找出开始,每个“链接”的结束 - 所以,如果一个链接到bb链接到ç,然后ç链接到d ,我想输出链接一个d联合亲子行 - TSQL

我想我最好避免使用与循环的过程,所以任何建议,将不胜感激!

的原始数据集和所需的输出如下所示:

personID | form | linkedform 
---------|---------|--------- 
    1 | a | b 
    1 | b | c 
    1 | c | d 
    1 | d | NULL 
    2 | e | f 
    2 | f | g 
    2 | g | NULL 
    2 | h | i 
    2 | i | NULL 
    3 | j | NULL 
    3 | k | l 
    3 | l | NULL 

希望的输出:

personID | form | linkedform 
---------|---------|--------- 
    1 | a | d 
    2 | e | g 
    2 | h | i 
    3 | j | NULL 
    3 | k | l 

每个PERSONID可以有多个链接以及链接可以由仅一个或多个的形式。

+0

这看起来像使用max函数的简单GROUPBY。 编辑:关于第二个想法,也许不是...... – user2366842

+0

在我看来,你希望每个人的所有形式的叶节点,这是在tSQL中用递归CTE处理的。 @ user2366842我不这么认为。查看存在多条路径的personID 3或2。 – xQbert

+0

下面是和[SQL小提琴](http://sqlfiddle.com/#!6/9100c/2)示出了递归CTE。从这里开始,所需的输出只有几步之遥。 – xQbert

回答

0
-- use a recursive cte to build the hierarchy 
-- start with [linkedform] = null and work your way up 
;WITH cte AS 
(
    SELECT *, [form] AS [root], 
      1 AS [Level] 
    FROM Table1 
    WHERE [linkedform] IS NULL 
    UNION ALL 
    SELECT t1.*, 
      [root], 
      [Level] + 1 
    FROM Table1 t1 
    JOIN cte ON cte.form = t1.linkedform 
) 
-- level 1 will be the last element, use row_number to get the first element 
-- join the two together based on last and first level, that have the same personid and root ([linkedform] = null) 
SELECT cte.personId, 
     cte2.form, 
     cte.form 
FROM cte 
     JOIN ( SELECT *, 
         ROW_NUMBER() OVER (PARTITION BY personId, [root] ORDER BY Level DESC) Rn 
       FROM cte) cte2 
      ON cte2.Rn = cte.Level 
       AND cte2.personId = cte.personId 
       AND cte2.root = cte.root 
WHERE cte.[Level] = 1 
ORDER BY cte.personId, cte2.form 
+0

非常感谢您的支持(以及有用的额外评论)。非常感激! – Leigh