SQL 如何在层次关系中将父节点的数据填入子节点的空值 *

有数据库表EXAMPLE,数据如下所示:

PK FK PARENT
001 23 000
002 null 001
003 46 001
004 12 000
005 null 004
006 null 005

某些记录FK字段为null,需将其替换为“最近的上级节点的FK”,如果父节点也是null,则继续向上递归找。输出时将PK替换为缩进格式,结果如下所示:

PK FK PARENT
 001 23 000
  002 23 001
  003 46 001
 004 12 000
  005 12 004
   006 12 005

OracleSQL

SELECT

    LPAD(' ',LEVEL) || PK AS PK,

    NVL(FK, REGEXP_SUBSTR(SYS_CONNECT_BY_PATH(FK,'/'),'(\d+)/*$',1,1,'',1)) AS FK,

    PARENT

FROM EXAMPLE

START WITH PARENT='000' CONNECT BY PRIOR PK = PARENT;

这道题需要用递归运算来解,将当前FK替换为最近的上一级节点的FK。虽然Oracle实现递归查询难度不大,但后续计算中需要引用上一级的FK,而在SQL中并没有显式的记录、引用这些概念,只能用正则表达式处理由递归关系拼成的串,难度有点大。

 

用开源集算器的SPL就很容易写,不用理解复杂的正则表达式:


A
1 =connect("oracle")
2 =A1.query@x("SELECT * FROM EXAMPLE")
3 >A2.switch(PARENT,A2:PK)
4 >A2.run(p=~.prior(PARENT),PK=fill(" ",p.len())+PK,FK=p.(FK).ifn())
5 >A2.run(PARENT=if(PARENT==null,"000",trim(PARENT.PK)))

SPL直接支持显示的记录,可以将外键引用转成记录型字段,很容易处理递归后续的计算问题。

问答搜集

https://stackoverflow.com/questions/64128476/overwriting-nulls-with-parent-data-in-a-hierarchical-query