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
Oracle的SQL:
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直接支持显示的记录,可以将外键引用转成记录型字段,很容易处理递归后续的计算问题。
英文版