创建cte语句以遍历使用桥表创建的树

时间:2018-05-05 00:11:13

标签: sql tree common-table-expression

我将在序言中说我对cte语句完全不熟悉。

我有2个表项表和链接表。链接器表包含关系的父ID和子ID。 我已经看到很多关于如何使用我认为称为关联系统遍历树的示例,其中父ID存储在子记录而不是桥表中。但我似乎无法根据我的情况推断出这一点。 我相信我需要有这样的桥牌表,因为任何一个项目都可能有多个父母,每个父母很可能有多个孩子。

我一起攻击了我自己遍历树的方式,但它是在另一种语言中,xojo,我真的不喜欢它的结果。基本上我每次使用递归函数挖掘每棵树,并在每次需要孩子时查询数据库。

现在我正在尝试创建一个执行相同操作的cte语句。将后代命令保持在父母之下并不是一件大事。

所以我创建了一个示例数据库和其他材料来描述我的问题:

此图表直观地显示了这些关系: diagram

这是我想从数据库返回的内容(某些项目显示在多个位置:

    1 : Audio
        2 : Speaker
        3 : Microphone
        4 : Mic Pack
            3 : Microphone
            5 : Di
                6 : Passive Di
                    11 : Rapco Di
                    13 : Dbx Di
    7 : Lighting
        9 : Safety
            12 : Small Safety
    8 : Rigging
        10 : Light Rigging
            9 : Safety
                12 : Small Safety

示例表:     CREATE TABLE itemsid INTEGER,name TEXT,PRIMARY KEY(id));

CREATE TABLE `linker` ( `parent` INTEGER, `child` INTEGER, PRIMARY KEY(`parent`,`child`) );

Insert Into items(id, name) Values(1, 'Audio');
Insert Into items(id, name) Values(2, 'Speaker');
Insert Into items(id, name) Values(3, 'Microphone');
Insert Into items(id, name) Values(4, 'Mic Pack');
Insert Into items(id, name) Values(5, 'Di');
Insert Into items(id, name) Values(6, 'Passive Di');
Insert Into items(id, name) Values(7, 'Lighting');
Insert Into items(id, name) Values(8, 'Rigging');
Insert Into items(id, name) Values(9, 'Safety');
Insert Into items(id, name) Values(10, 'Lighting Rigging');
Insert Into items(id, name) Values(11, 'Rapco Di');
Insert Into items(id, name) Values(12, 'Small Safety');
Insert Into items(id, name) Values(13, 'Dbx Di');

Insert Into linker(parent, child) Values(1, 2);
Insert Into linker(parent, child) Values(1, 4);
Insert Into linker(parent, child) Values(1, 3);
Insert Into linker(parent, child) Values(4, 3);
Insert Into linker(parent, child) Values(4, 5);
Insert Into linker(parent, child) Values(5, 6);
Insert Into linker(parent, child) Values(6, 11);
Insert Into linker(parent, child) Values(6, 13);
Insert Into linker(parent, child) Values(7, 9);
Insert Into linker(parent, child) Values(9, 12);
Insert Into linker(parent, child) Values(8, 10);
Insert Into linker(parent, child) Values(10, 9);

这是我提出的cte,我相信它是最接近的,但它可能仍然相当遥远:

  with cte As
    (
    Select 
        id,
   name,
   0 as level,
   Cast(name as varchar(255) as sort
    From items i
    Left outer Join
    linker li
    On i.id = li.child
    And li.parent is Null

    Union All

    Select 
        id,
        name,
        cte.level + 1,

        Cast(cte.sort + '.' + i.name As Varchar(255)) as sort
    From cte
    Left Outer Join linker li
    on li.child = cte.id
    Inner Join items i
    On li.parent = i.id
    )

Select 
    id,
    name,
    level,

    sort
From cte
Order By Sort;

提前感谢您的帮助。我非常乐观地认为我从数据结构中所做的一切都是错误的,所以在你回答时请记住这一点。

编辑:可能值得注意的是,结果不需要整齐。我计划在cte语句中创建一个祖先路径字段,并使用该patb填充我的树。

编辑:oops,我复制并粘贴了错误的cte代码。我在移动设备上,所以我尽力将其更改为我在桌面上所做的事情。一旦我有机会,我会仔细检查我的笔记的cte声明。

1 个答案:

答案 0 :(得分:1)

好吧,好像我的大脑需要休息一下。我已经找到了解决问题的方法,而且比昨天更加沮丧。

我的cte声明是:

with cte As(
    Select 
       id,
       name, 
       li.parent,
       li.child,
       Cast(name as Varchar(255)) as ancestory
    From items i
    Left Outer Join linker li
    On i.id = li.child
    Where li.parent is null

    Union All

    Select 
        i.id,
        i.name,
        li.parent,
        li.child,
        Cast(cte.ancestory || "." || i.name as Varchar(100)) as ancestory
    From cte
    Left join linker li
    On cte.id = li.parent
    Inner Join items i
    On li.child = i.id

        )
select * from cte

结果如下:

  id    name        parent    child    ancestory
   1    Audio                          Audio
   7    Lighting                       Lighting
   8    Rigging                        Rigging
   2    Speaker       1          2     Audio.Speaker
   3    Microphone    1          3     Audio.Microphone
   4    Mic Pack      1          4     Audio.Mic Pack
   9    Safety        7          9     Lighting.Safety
  10    Lighting      8         10     Rigging.Lighting Rigging
         Rigging
   3    Microphone    4          3     Audio.Mic Pack.Microphone
   5    Di            4          5     Audio.Mic Pack.Di
  12    Small         9         12     Lighting.Safety.Small Safety
         Safety
   9    Safety       10          9     Rigging.Lighting Rigging.Safety
   6    Passive Di    5          6     Audio.Mic Pack.Di.Passive Di
  12    Small Safety  9         12     Rigging.Lighting Rigging.Safety.Small Safety
  11    Rapco Di      6         11     Audio.Mic Pack.Di.Passive Di.Rapco Di
  13    Dbx Di        6         13     Audio.Mic Pack.Di.Passive Di.Dbx Di