Вывод открывающих и закрывающих элементов для дерева - PullRequest
0 голосов
/ 22 мая 2018

У меня есть древовидная структура в 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 голосов
/ 15 августа 2018

Нам нужно обработать два тега на человека, поэтому создайте виртуальную таблицу 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...