输出树的开始和结束元素

时间:2018-05-22 15:41:07

标签: sqlite tree nested recursive-query

我在SQLite中有一个树结构,我希望查询自动添加结束元素(如编程语言中的括号或XML中的结束标记)。

CREATE TABLE org(id int primary key, name text, boss int, sibling int);

INSERT INTO org VALUES(0, 'Alice', NULL, null);
INSERT INTO org VALUES(1, 'Bob', 0, null);
INSERT INTO org VALUES(2, 'Cindy', 0, 1);
INSERT INTO org VALUES(3, 'Dave', 1, 4);
INSERT INTO org VALUES(4, 'Emma', 1, null);
INSERT INTO org VALUES(5, 'Fred', 2, null);
INSERT INTO org VALUES(6, 'Gail', 2, 5);

到目前为止我的查询:

WITH RECURSIVE OrderedOrg(id, name, boss, SiblingOrder) AS (
 SELECT id, name, boss, 0 FROM org 
 WHERE sibling IS NULL 
 UNION ALL 
 SELECT org.id, org.name, org.boss, OrderedOrg.SiblingOrder + 1 
 FROM org 
 JOIN OrderedOrg ON org.boss    = OrderedOrg.boss 
 AND org.sibling = OrderedOrg.id
),
under_alice(id, name,SiblingOrder,level) AS (
 select id, name,0,0 from org where id = 0 
 UNION ALL 
 SELECT OrderedOrg.id, OrderedOrg.name, OrderedOrg.SiblingOrder, under_alice.level+1 
 FROM OrderedOrg JOIN under_alice ON OrderedOrg.boss=under_alice.id 
 ORDER BY 4 DESC, 3 DESC
)
SELECT group_concat(name) FROM under_alice;

结果:

Alice,Cindy,Gail,Fred,Bob,Dave,Emma

预期结果:

<Alice><Cindy><Gail></Gail><Fred></Fred></Cindy><Bob><Dave></Dave><Emma></Emma></Alice>

1 个答案:

答案 0 :(得分:1)

我们必须每个人处理两个标签,因此创建一个虚拟表two,我们可以在加入时使用该表生成两个输出行。连接条件x = 1确保仅在开始标记之后进行递归:

WITH RECURSIVE OrderedOrg ...,
two(x) AS (
  VALUES (1), (2)
),
tree AS (
  SELECT *
  FROM (SELECT o.*, 0 AS level, two.x
        FROM OrderedOrg AS o
        CROSS JOIN two
        WHERE boss IS NULL
        ORDER BY x)

  UNION ALL

  SELECT o.id, o.name, o.boss, o.SiblingOrder, tree.level + 1, two.x
  FROM tree
  JOIN OrderedOrg AS o ON tree.x = 1
                      AND tree.id = o.boss
  CROSS JOIN two

  ORDER BY level DESC, SiblingOrder DESC, x
)
SELECT group_concat(CASE x
                    WHEN 1 THEN '<'
                    ELSE        '</'
                    END || name || '>', '')
FROM tree;