我在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>
答案 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;