Oracle SQL实现:将父子谱系数据按顺序汇总展示
问题场景
我手上有一张记录父子关系的表,数据如下:
src_data date dst_data key --------------------------------------------- P1 2018-01-01 D2 123 D2 2018-01-02 D3 123 D3 2018-01-03 D4 123
我想写一条Oracle SQL语句,把同一个key对应的所有节点按顺序列出来,得到这样的结果:
key link ----------------- 123 P1 123 D2 123 D3 123 D4
请问该怎么实现?感谢帮忙!
解决方案
其实这个需求就是要把关系链里的所有节点(起始节点+后续的子节点)都提取出来,按时间顺序排列对吧?这里给你两种可行的实现方式:
方法一:精准定位起始节点(更严谨)
这种方式会先找到链条的起始节点(也就是没有出现在dst_data里的src_data),再把所有子节点合并进来,逻辑更清晰:
WITH chain_nodes AS ( -- 提取链条的起始节点:找那些从未作为子节点出现的父节点 SELECT src_data AS link, key, date AS sort_date FROM your_table WHERE src_data NOT IN (SELECT dst_data FROM your_table) UNION ALL -- 提取所有子节点 SELECT dst_data AS link, key, date AS sort_date FROM your_table ) SELECT key, link FROM chain_nodes ORDER BY key, sort_date;
方法二:直接合并所有节点(更简洁)
如果你的数据里每个key对应的链条是唯一的,且不会出现一个节点同时属于多个链条的情况,也可以直接把src_data和dst_data合并后排序:
SELECT key, link FROM ( SELECT src_data AS link, key, date FROM your_table UNION ALL SELECT dst_data AS link, key, date FROM your_table ) ORDER BY key, date;
逻辑说明
- 两种方法核心都是用
UNION ALL把父节点列和子节点列合并成一个link列; - 通过
date字段排序,保证节点顺序和原表的时间顺序一致; - 方法一的优势是能避免重复节点(比如如果某个节点既是A链条的子节点,又是B链条的父节点,方法一会精准提取它作为B链条的起始节点一次),而方法二会保留所有出现的记录,你可以根据实际数据情况选择。
内容的提问来源于stack exchange,提问作者Ianthe
相关产品推荐
相关产品推荐

