暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 纵向和横向层次链

ASKTOM 2021-04-28
414

问题描述

嗨,克里斯,

表T存储了四种类型的零件关系-单边,双边,营销/促销和工具包,并且要求是确定物品关系链。

关系类型 “s” 表示已取代,并与关系方向 “o” 单边 (即A -> B -> C) 和 “t双边 (D -> e <-> F) 结合

关系类型 “m” 是营销/促销目的所需的多个部分。关系方向在这里无关紧要,并且在这种关系中只能有一个父级 (Y -> Y1,Y -> Y2)。

最后一个关系由具有值 “c” 的组件列标识,这意味着关系的组件类型,关系方向在这里无关紧要,并且这种关系中只能有一个父关系。

从DUAL UNION ALL中选择 'X','S','x1','null,'C',即具有relation_type 'S' 和component为 'C' 的行表示套件的主要部分。

从DUAL UNION ALL中选择 'X','R','x2','x2','C','C',即具有relation_type 'R' 和component为 'C' 的行表示套件的次要部分。

X -> X1

X -> X2
“项目” 是一个套件,由关系类型 'M' 或component = 'C' 识别,或者它是一个 “单个项目” (由与 'M' 和null component不同的关系类型识别)。在套件的情况下,我希望查询仅返回直接子代 (直接后代),而对于 “单个项目”,我希望看到后代的整个层次结构。

在单边关系中,你只能在链中前进,但在双边关系中,你必须后退一步,检查上一步中的项目是否也有双边关系,如果再次是,请退后一步,直到您达成单方面关系,然后开始前进,例如E <> F。

Expected output-

When passed item A as parameter then-

亲子

A B

在这里应该忽略一行的C B,因为这是不正确的递归关系。

When passed item B as parameter then-

亲子

B C

When passed item D as parameter then-

亲子

D E

D F

When passed item E as parameter then-

亲子

E F

当传递项目F作为参数时 (因为E <-> F遍历返回)-

亲子

E F

当传递项目Y作为参数时 (检查零件的关系类型M的唯一行)-

亲子

Y Y1

Y Y2

当传递项目X作为参数时,然后 (检查组件的唯一行作为C的部分)-

亲子

X X1

X X2

实时SQL链接中的示例数据和代码给出了理想的结果,但在下面的两种情况下,我想在解决方案中进行管理。

Case 1-When the is full bilateral relation P <> Q <> R <> S <> T, the expectation is as below when you pass T item -

亲子
P Q
P R
P S
P T


如何在输出中添加order by?
如何以任何方式从查询中删除不同的逻辑?



专家解答

我不确定我是否完全理解要求。

例如,如果输入为S,输出应该是什么?和T一样还是别的什么?如果T和P之间有一条边会发生什么?

另外B具有B -> A和B -> C,那么如果这是输入,为什么只想要B -> C?

无论如何,这里有一个解决方案的概要,应该让你开始:

-从输入节点,尝试根据关系类型在树上下移动
-下降时,整体父母是根
-上升时,整体父级是叶子 (如果路径有很多叶子,会发生什么?)
-这样做时,排除与其他方向上的电流具有相同顶点的任何边
-将两棵树的结果联合在一起
-通过以下方式找到整体父母:
-来自向上分支的最后一片叶子 (如果存在)
-如果没有向上,向下的根

您可以通过使用last_value来完成最终操作,首先按UP/DOWN排序行,然后按UP和DOWN的树顺序反向排序:

with up ( rt, nd, lvl, direction ) as (
  select  case when connect_by_isleaf = 1 then v1 end rt,
          v2, level, 'UP' direction
  from    t 
  where   connect_by_iscycle = 0 
  start   with v2 = :item 
  and   relation_direction = 'T' 
  and ( v1, v2 ) not in ( select v2, v1 from t )
  connect by nocycle relation_direction = 'T' 
  and prior v1 = v2 
  and ( v1, v2 ) not in ( select v2, v1 from t )
), down ( rt, nd, lvl, direction ) as (
  select  connect_by_root(v1), v2, level, 'DOWN' direction
  from    t 
  where   connect_by_iscycle = 0 
  start   with v1 = :item 
  connect by nocycle prior relation_type != 'M' 
  and prior component is null 
  and v1 = prior v2 
  and ( v1, v2 ) not in ( select v2, v1 from t )
), tree as (
  select * from down
  union all
  select * from up
)
  select t.*, 
         first_value (
           rt
         ) over ( 
            order  by case 
              when direction = 'UP' then 1 else 2 
            end, case 
              when direction = 'UP' then -lvl else lvl
            end    
         ) parent
  from   tree t
  order  by case 
    when direction = 'UP' then 1 else 2 
  end, case 
    when direction = 'UP' then -lvl else lvl
  end;


这主要给出了你请求的输出 (虽然输入B,你会得到B -> A和B -> C),我猜想,当传递S,R等,你想要相同的输出作为T。

connect by子句可能特定于您传递的数据; 我不相信这些将推广到您的完整数据集。
文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论