加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

sql – 递归查询挑战 – 简单的父/子示例

发布时间:2020-12-12 07:50:04 所属栏目:MsSql教程 来源:网络整理
导读:注意:在# postgresql上的RhodiumToad的帮助下,我已经找到了一个解决方案,我将其作为答案发布.如果有人可以改善这个,请进来! 我没有能够将previous recursive query solution修改为包含多个“根”(无祖先)节点的以下有向非循环图.我正在尝试编写一个查询,其
注意:在# postgresql上的RhodiumToad的帮助下,我已经找到了一个解决方案,我将其作为答案发布.如果有人可以改善这个,请进来!

我没有能够将previous recursive query solution修改为包含多个“根”(无祖先)节点的以下有向非循环图.我正在尝试编写一个查询,其输出通常被称为闭包表:一个多对多表,将每个节点的每个路径存储到每个后代及其自身:

1  2  11  8  4  5  7
 /    |  |    | /
  3    |       6
      |      /
    9  |     10
     /     /
     12    13
         /
        14

CREATE TABLE node (
  id        SERIAL PRIMARY KEY,node_name VARCHAR(50) NOT NULL
);

CREATE TABLE node_relations (
  id                 SERIAL PRIMARY KEY,ancestor_node_id   INT REFERENCES node(id),descendant_node_id INT REFERENCES node(id)
);

INSERT into node (node_name)
SELECT 'node ' || g FROM generate_series(1,14) g;

INSERT INTO node_relations(ancestor_node_id,descendant_node_id) VALUES
(1,3),(2,(4,6),(5,(7,(3,9),(6,10),(8,(9,12),(11,(10,13),(12,14),(13,14);

很难确定问题 – 我是否缺少node_relation行?查询错了吗?

WITH RECURSIVE node_graph AS (
   SELECT ancestor_node_id,ARRAY[descendant_node_id] AS path,0 AS level
   FROM   node_relations

   UNION  ALL
   SELECT nr.ancestor_node_id,ng.path || nr.descendant_node_id,ng.level + 1 AS level
   FROM   node_graph ng
   JOIN   node_relations nr ON nr.descendant_node_id = ng.ancestor_node_id 
)
SELECT path[array_upper(path,1)] AS ancestor,path[1] AS descendant,path,level as depth
FROM   node_graph
ORDER  BY level,ancestor;

预期产量:

ancestor | descendant | path
---------+------------+------------------
1        | 3          | "{1,3}"
1        | 9          | "{1,3,9}"
1        | 12         | "{1,9,12}"
1        | 14         | "{1,12,14}"
2        | 3          | "{2,3}"
2        | 9          | "{2,9}"
2        | 12         | "{2,12}"
2        | 14         | "{2,14}"
3        | 9          | "{3,9}"
3        | 12         | "{3,12}"
3        | 14         | "{3,14}"
4        | 6          | "{4,6}"
4        | 10         | "{4,6,10}"
4        | 13         | "{4,10,13}"
4        | 14         | "{4,13,14}"
5        | 6          | "{5,6}"
5        | 10         | "{5,10}"
5        | 13         | "{5,13}"
5        | 14         | "{5,14}"
6        | 10         | "{6,10}"
6        | 13         | "{6,13}"
6        | 14         | "{6,14}"
7        | 6          | "{7,6}"
7        | 10         | "{7,10}"
7        | 13         | "{7,13}"
7        | 14         | "{7,14}"
8        | 10         | "{8,10}"
8        | 13         | "{8,13}"
8        | 14         | "{8,14}"
9        | 12         | "{9,12}"
9        | 14         | "{9,14}"
10       | 13         | "{10,13}"
10       | 14         | "{10,14}"
11       | 12         | "{11,12}"
11       | 14         | "{11,14}"
12       | 14         | "{12,14}"
13       | 14         | "{13,14}"

解决方法

在#postgresql的RhodiumToad帮助下,我已经到达了这个解决方案:
WITH RECURSIVE node_graph AS (
    SELECT ancestor_node_id as path_start,descendant_node_id as path_end,array[ancestor_node_id,descendant_node_id] as path 
    FROM node_relations

    UNION ALL 

    SELECT ng.path_start,nr.descendant_node_id as path_end,ng.path || nr.descendant_node_id as path
    FROM node_graph ng
    JOIN node_relations nr ON ng.path_end = nr.ancestor_node_id
) 
SELECT * from node_graph order by path_start,array_length(path,1);

结果与预期完全一样.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读