材料清单和CTE(MariaDB)

时间:2020-07-15 08:39:19

标签: mariadb common-table-expression

这是我第一次来这里提问,因此我希望足够清晰地得到答案。

我有馆藏,需要在它们之间建立关系。每个集合都应该是其他任何集合的子对象(及其子对象)。

定义的关系(带有ID)的示例如下:

2
|-3
|-4

5
|-3

4
|-5

现在,当收起一棵树进行收集2时,我需要得到(期望):

2
|-3
|-4
  |-5
    |-3

但是得到:

2
|-3
|-4
  |-5

测试表:

CREATE TABLE collection_bom (
    id INT,
    collection_id varchar(20),
    reference_id varchar(20)
);

-- definition 2-3-4 relationship
INSERT INTO collection_bom(id,collection_id,reference_id) VALUES (1,2,NULL);
INSERT INTO collection_bom(id,collection_id,reference_id) VALUES (2,3,1);
INSERT INTO collection_bom(id,collection_id,reference_id) VALUES (3,4,2);
-- definition of 5-3 relationship
INSERT INTO collection_bom(id,collection_id,reference_id) VALUES (4,5,NULL);
INSERT INTO collection_bom(id,collection_id,reference_id) VALUES (5,3,4);
-- definition of 4-5 relationship
INSERT INTO collection_bom(id,collection_id,reference_id) VALUES (6,5,3);

查询:

with recursive cte as (
      select t.*
      from collection_bom t
      where reference_id IS NULL AND collection_id = 2
      union all
      select t.*
      from cte join
           collection_bom t
           on cte.id = t.reference_id
     )
select *
from cte;
Result:
id  collection_id   reference_id
1   2               null
2   3               1
3   4               2
6   5               3

结果,我还需要将collection_id 3作为5的孩子。

现在,我意识到这可能不是一个好方法。 任何帮助表示赞赏!

Fiddle

1 个答案:

答案 0 :(得分:0)

您在插入部分遇到语义问题; 5-3关系的定义从头开始创建新树(使用NULL引用),该树与原始树无关。因此,您在第二棵树中定义的“ 5”与第一棵树中的其他“ 5”不同。 在4-5关系的定义中,您不使用NULL引用,而是将其链接到第1个表中的引用,因此效果很好。

此插入部分可以执行您想要的操作:

-- definition 2-3-4 relationship
INSERT INTO collection_bom(id,collection_id,reference_id) VALUES (1,2,NULL);
INSERT INTO collection_bom(id,collection_id,reference_id) VALUES (2,3,1);
INSERT INTO collection_bom(id,collection_id,reference_id) VALUES (3,4,1);
-- definition of 4-5 relationship
INSERT INTO collection_bom(id,collection_id,reference_id) VALUES (4,5,3);
-- definition of 5-3 relationship
-- INSERT INTO collection_bom(id,collection_id,reference_id) VALUES (4,5,NULL);
INSERT INTO collection_bom(id,collection_id,reference_id) VALUES (5,3,4);