【问题标题】:Teradata SQL Reverse Parent Child HierarchyTeradata SQL 反向父子层次结构
【发布时间】:2017-04-12 04:20:24
【问题描述】:

我知道如何从根节点开始构建层次结构(即 parent_id 为 null 或类似的东西),但我找不到任何关于如何从最终子/边缘节点向上构建层次结构的信息。我想从一个孩子开始,一直建到顶峰。假设我不知道有多少层,也不知道父母是谁,我们将不得不使用 SQL 来弄清楚。

这是我的基表:

old_entity_key,new_entity_key
1,2
2,3
3,4
4,5
5,6

期望的输出:

new_entity_key,path
2,1/2
3,1/2/3
4,1/2/3/4
5,1/2/3/4/5
6,1/2/3/4/5/6

这也是可以接受的:

new_entity_key,path
2,2/1
3,3/2/1
4,4/3/2/1
5,5/4/3/2/1
6,6/5/4/3/2/1

这是我开始使用的 CTE:

with recursive history as (
    select
        old_entity_key,
        new_entity_key,
        cast(old_entity_key||'/'||new_entity_key as varchar(1000)) as path
    from table
    where new_entity_key not in (select old_entity_key from table)
        and cast(start_time as date) between current_date - interval '3' day and current_date
    union all
    select
        c.old_entity_key,
        c.new_entity_key,
        p.new_entity_key||'/'||c.path
    from history c
    join table p on p.new_entity_key = c.old_entity_key
)
select new_entity_key, old_entity_key, substr(path, 1, instr(path, '/') - 1) as original_entity_key, path
from history s;

上述查询的问题是它永远运行。我想我已经创建了一个无限循环。我还尝试在union 的底部查询中使用下面的where 过滤器来尝试查找根节点,但是 Teradata 给了我一个错误:

where p.new_entity_key in (select old_entity_key from table)

任何帮助将不胜感激。

【问题讨论】:

    标签: sql teradata common-table-expression


    【解决方案1】:

    您需要某种计数器,我认为您在 CTE 中的联接逻辑没有意义。我整理了一个非常简单的 volatile 表示例:

    create volatile table tb 
    (old_entity_key char(1),
    new_entity_key char(1),
    rn integer)
    on commit preserve rows;
    
    insert into tb values ('1','2',1);
    insert into tb values ('2','3',2);
    insert into tb values ('3','4',3);
    

    现在我们可以组合一个递归 CTE:

    with recursive history as (
    select
        old_entity_key,
        new_entity_key,
        cast(old_entity_key||'/'||new_entity_key as varchar(1000)) as path,
        rn
    from tb t
    where
         rn = 1
    
    union all
    select
        t.old_entity_key,
        t.new_entity_key,
        h.path || '/' || t.new_entity_key,
        t.rn
    from
         tb t
        join history h
            on t.rn = h.rn + 1
    )
    select * from history order by rn
    

    这里重要的事情是:

    1. 限制您的第一次通过(由rn=1 在此处完成)。

    2. 第二遍需要在上一行(t.rn = h.rn + 1)的基础上拾取“下一个”行

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-23
      • 2020-05-29
      • 1970-01-01
      相关资源
      最近更新 更多