拼合分层表

时间:2014-09-10 17:29:25

标签: sql sql-server

从这里开始跟进:Getting lowest level in a tree from any higher level with a self-join

我意识到我实际上是在问错误的问题。我有一个分层表,看起来像这样:

Type | Code  | Parent_Type | Parent_Code
  4  | 123   |     2       |     1
  4  | 234   |     2       |     1
  6  | 1234  |     4       |     123 
  6  | 2345  |     4       |     234
  7  | 12345 |     6       |     1234
  7  | 23456 |     6       |     1234
  7  | 34567 |     6       |     2345

它映射"类型2"代码为"类型4","类型4"到"类型6"和"类型6"到"输入7"。上一个问题(和答案)涉及如何在任何单个父代码下选择所有类型7代码。因此,例如,如何获得类型2下的所有类型7代码,代码1。

但我真正需要做的是将此表与类型和代码列表联系起来。例如,我可能有一张表:

Type | Code  
  4  | 123
  6  | 7851

我需要做的是在 这些代码下获取所有7级代码。换句话说,(我认为)我需要将层次结构扁平化为这样的东西:

Type | Code  | Parent_Type | Parent_Code
  7  | 12345 |     2       |     7
  7  | 23456 |     2       |     7
  7  | 34567 |     2       |     7
  7  | 12345 |     4       |     123
  7  | 23456 |     4       |     123
  7  | 34567 |     4       |     234
  7  | 12345 |     7       |     12345     // Note: these last three might not 
  7  | 23456 |     7       |     23456     // be strictly needed
  7  | 34567 |     7       |     34567 

那么我可以这样做:

 select p.type, p.code from myOtherTable o join mytable p on o.type = p.parent_type 
 and o.code = p.parent_code

为了尝试压扁原始表格,我在原始问题的答案上尝试了一些变化,但没有真正的运气。例如:

with cte
as (
select p.type, p.code, p.parent_type, p.parent_code
from mytable as p
where parent_type = 2

union all

select c.type, c.code, c.parent_type, c.parent_code
from mytable as c
inner join cte on c.parent_code = cte.code
)
select *
from cte

如果我只是直接调用,那么除了搞乱表格的排序之外没有什么用处:

select * from mytable

1 个答案:

答案 0 :(得分:1)

听起来像递归CTE应该可以解决这个问题:

WITH cteTree As
(
  SELECT
    T.Type,
    T.Code,
    T.Parent_Type,
    T.Parent_Code
  FROM
    RecordsToFind As F
    INNER JOIN Tree As T
    ON T.Type = F.Type
    And T.Code = F.Code

  UNION ALL

  SELECT
    T.Type,
    T.Code,
    T.Parent_Type,
    T.Parent_Code
  FROM
    cteTree As F
    INNER JOIN Tree As T
    ON T.Parent_Type = F.Type
    And T.Parent_Code = F.Code
  WHERE
    F.Type != 7
)
SELECT
  Type,
  Code,
  Parent_Type,
  Parent_Code
FROM
  cteTree
WHERE
  Type = 7
;

http://sqlfiddle.com/#!3/cc4ee/9